2009-11-26 13 views
11

Quando valutano (uso 'ciao) per caricare hello.clj, il REPL si lamenta con il seguente errore:Clojure non riesce a trovare .clj nella directory locale,. e ./classes su CLASSPATH

java.io.FileNotFoundException: Could not locate hello__init.class or hello.clj on classpath: (NO_SOURCE_FILE:0) 

sto invocando il REPL in questo modo:

java -cp "/Library/Java/Extensions/servlet-api-2.5-20081211.jar:... lots of jarfiles ...:/Library/Java/Extensions/clojure-contrib.jar:/Library/Java/Extensions/clojure-1.0.0.jar:./classes/:." jline.ConsoleRunner clojure.lang.Repl 

Leggendo intorno, sembra che il file non sia stato trovato nel PWD, ma ho aggiunto. al percorso senza successo :-(.

Correndo con Java 1.6 su OS X 10.6.

Sono sicuro che io sia un idiota, qualcuno può colpire con una LART?

EDIT: ho provato anche il ClojureX distro, ed ho ottenuto gli stessi risultati

+0

Cosa uscita si ottiene da: (println (SEQ (.getURLs (java.lang.Classloader/getSystemClassLoader)))) –

+0

Dal mio dir Clojure (/ Users/Ben/Documents/Codice/Clojure), ottengo questo : (# ... più urls per jarfiles ... # # # ) – afternoon

+0

poiché non ho visto questo dichiarato esplicitamente da qualche parte ancora e potrebbe avere rilevanza dove si trova il file ciao.clj? anche cosa succede se corri (compile 'ciao)? –

risposta

2

quando sto lavorando dal repl e vuole caricare i file che trovo devo chiamare qualcosa come questa:.

(add-classpath "file:///home/arthur/.../src/") 
(add-classpath "file:///home/arthur/.../build/") 

prima che il repl possa trovarli sul classpath. Inserisco questi in un file che non è incluso nel file jar insieme a un'istruzione che ricarica tutto dagli altri file. Quando costruisco un file jar trovo che non ho bisogno di farlo.

+2

Per favore non farlo! add-classpath è * solo * per sperimentare. Il modo giusto per una configurazione regolare è come l'OP ha fatto: impostare il classpath all'avvio della JVM. L'aggiunta di percorsi con add-classpath è regolarmente interrotta e tornerà a perseguitarti. Questo è solo il modo in cui è progettata la JVM. – kotarak

+0

Quando uso add-classpath come suggerito, funziona almeno abbastanza bene per trovare hello.clj e caricarlo.Sembra che add-classpath stia facendo qualcosa che la variabile env CLASSPATH non è. – afternoon

3

Hello.clj contiene una dichiarazione (ns some-namespace)? Se è così, allora same_namespace viene aggiunto alla ogni elemento del CLASSPATH prima di cercare hello.clj

+0

Non lo sapevo, grazie! Ho un paio di file di test. Uno definisce uno spazio dei nomi, l'altro no. Né lavoro purtroppo. Ho spostato il test di definizione dei nomi in una sottodirectory del classpath, ma ancora senza fortuna. – afternoon

+0

Avrei dovuto dire gli elementi principali di 'some-namespace'. Questo è un file con (ns some.namespace) dovrebbe essere chiamato 'namespace.clj' in una sottodirectory 'alcuni'. –

1

ho definito un alias (in .bash_profile) per caricare il REPL:

alias clojure='CLASSPATH=$HOME/git/clojure/clojure.jar:$HOME/git/clojure-contrib/clojure-contrib.jar:.:classes rlwrap java clojure.lang.Repl' 
13

Se hello.clj è in $DIR e $DIR è sul classpath, quindi hello.clj deve iniziare con (ns hello). Se è in $DIR/$SUBDIR e $DIR è nel classpath, quindi hello.clj deve iniziare con (ns $SUBDIR.hello). In generale, la struttura del nome del file e la struttura del nome ns devono corrispondere, con il separatore di file sostituito da . nel nome ns e qualsiasi _ s nel nome file corrispondente a - s nel nome ns. Il nome del file effettivo deve essere il componente finale (probabilmente l'unico componente, se il file contenente la dir è sul classpath) del nome dello spazio dei nomi.

EDIT:

Un esempio esteso. Nessuna informazione al di là di ciò che ho scritto sopra, quindi per favore saltane sopra se è sufficiente per te; tuttavia so che ottenere il CP giusto è stato abbastanza doloroso per me all'inizio, quindi ho deciso di scrivere questo in modo graduale in modo che qualcuno, da qualche parte, potesse forse essere risparmiato da quella particolare "esperienza di apprendimento" ;-).

dicono che questa è la sua definizione dello spazio dei nomi:

;;; in file "hello.clj" 
(ns hello) 

(defn hello [] 
    (println "Hello!")) 

Quindi se si mette la directory che contiene hello.clj sul classpath, siete pronti per andare a un (use 'hello) al REPL dovrebbe fare quello che vuoi.

Se, d'altra parte, si esegue questa operazione:

;;; in file "hello.clj" 
(ns my-namespace) 
;;; ... 

o questo:

;;; in file "my-filename.clj" 
(ns hello) 
;;; ... 

- vale a dire, se si introduce una mancata corrispondenza tra il nome del file e il nome dello spazio dei nomi, Clojure non sarà in grado di trovare il tuo spazio dei nomi.

Inoltre, se si mette in hello.clj/path/to/code, ma quello che avete sul vostro percorso di classe è in realtà /path/to, vale a dire la directory padre di /path/to/code, è necessario fare questo:

;;; in file "/path/to/code/hello.clj" 
(ns code.hello) 
;;; ... 

Allora sarete in grado a (use 'code.hello).

Infine, se si chiama il file my_namespace.clj, è necessario chiamare il numero my-namespace (e viceversa). _ s nei nomi degli spazi dei nomi e nei nomi dei file - non devono essere utilizzati.

+0

Grazie mille per aver preso così tanti dettagli qui. Ho esaminato tutti i tuoi esempi e ancora non ho avuto fortuna. Penso che il mio sistema debba essere rotto in qualche modo. – afternoon

+0

Sicuro. Ma, um ... non funziona ancora !? A questo punto sono propenso a condividere i tuoi sospetti. Pubblicherò tutte le domande di follow-up come commenti alla domanda, se riesco a pensare a qualsiasi ... Buona fortuna! –

+1

Sono sorpreso dal fatto che Clojure stia prendendo la doppia codifica di Java della dichiarazione del pacchetto sintattico e del percorso della directory fisica un ulteriore passo avanti, e ora richiede che anche il nome del file faccia parte dello spazio dei nomi, anche se non ci devono essere classi generate su nome di un determinato file. In CL, i pacchetti sono separati dai file di origine. In Clojure, gli spazi dei nomi dovrebbero essere divorziabili dai file? Lo spazio dei nomi dovrebbe essere esteso a più file di origine contributivi? La documentazione di Clojure è muta su questo punto. – seh

1

Ho le seguenti linee sul .emacs:

(setq swank-clojure-jar-path "~/src/clojure/clojure.jar" 
     swank-clojure-extra-classpaths (append 
         (directory-files "~/src/compojure/deps" t ".jar$") 
         (list 
         "~/src/swank-clojure/src/main/clojure" 
         "~/src/clojure-contrib/clojure-contrib.jar" 
         "~/src/clj/."))) 

carico la snake.clj programmi che è a ~/src/CLJ e Eval esso (Cx h che seleziona l'intero buffer e poi Cc Cc per compilare). I programmi creano uno spazio dei nomi per nome snake. Ora, da emacs/melma, faccio

(use 'snake) 

Ecco it.Now ricorrere ad ogni funzione definita nello spazio dei nomi.

Il tuo problema potrebbe essere che la directory su cui hai hello.clj potrebbe non trovarsi sul classpath. Assicurati inoltre di nominare correttamente lo spazio dei nomi. Se all'interno ciao.clj, hai chiamato il tuo spazio dei nomi come ciao, poi lo fai (usa 'ciao').

Problemi correlati