2012-02-01 2 views
103

Sto lavorando per estendere il Grails Clojure plugin in Grails 2.0.0 (e 2.1.0-SNAPSHOT) e volevo aggiornarlo a Clojure 1.3.0 e aggiungere clojure.tools.logging.Il proxy Clojure 1.2.1/1.3/1.4 'generato nel runtime di Grails 2.0.0 non riesce. 1.2.0 va bene

Clojure genera un'eccezione durante la compilazione di un delega di una funzione di log-stream ByteArrayOutputStream in clojure.tools.logging s':

ClassCastException: clojure.asm.Type cannot be cast to clojure.lang.IFn

(https://gist.github.com/a6ae681c37091a3d2379)

sono andato ed ho rimosso clojure.tools.logging e ha scritto un prorogato proxy di Object:

(proxy [java.lang.Object] [] (toString [] "proxy's toString"))

ed è anche lanciato lo stesso ClassCastException e il messaggio.

ho cercato di stampare un macroexpand-1 del delega e ottenuto la stessa cosa.

Sono tornato a Clojure 1.2.0 e proxy ha funzionato di nuovo bene.

Ho provato un numero di incarnazioni di 1.4.0 e hanno lo stesso comportamento di 1.3.0. 1.2.1 lancia anche qualche sorta di eccezione, ma sto cercando di raggiungere 1.3.0, quindi non ho trascorso molto tempo con quello.

I punti della traccia dello stack alla 'funzione GEN-metodo definito in una delle lasciate forme di generate-proxy in core_proxy.clj.

Ho aggiunto una piccola infarinatura di lì intorno per vedere se riuscivo a capire cosa stava succedendo. Forse questa prossima dichiarazione tradirà un enorme fraintendimento del lettore da parte mia, ma aggiungendo semplicemente quelli println s ha cambiato il comportamento del tempo di compilazione in un modo che non mi aspettavo. La posizione di eccezione e il tipo di eccezione sono stati completamente modificati, anche se tutti i test Clojure in mvn package continuano a passare.

Per esempio, solo l'aggiunta di un singolo println a Gen-metodo giusto prima che inizia a generare bytecode causato Clojure per gettare

ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class

(https://gist.github.com/5a7a40929a6c4a104bd5)

Ho visto diversi altri errori a seconda su dove ho messo il println (s), ma questo è il più diffuso.

Ovviamente alcuni aspetti di Grails e Clojure non si inseriscono correttamente qui, ma non vedo la connessione. All'inizio sospettavo incompatibilità con ASM ma poiché Clojure ha il proprio spazio dei nomi ASM, non riesco a vedere che sia il problema.Ma forse ho sbagliato, ho guardato allo , al al proxy e al generano il proxy per giorni ora cercando di farlo funzionare e ho praticamente smesso di progredire perché sono a corto di a vapore :(

mi scuso per la mancanza di collegamenti è possibile copiare e incollare dal basso:.

Grails Clojure - github.com/grails-plugins/grails-clojure

Clojure strumenti di registrazione - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj linea 133 è la 'delega

+4

Ho fatto altri test e sono quasi convinto che qualcosa in Grails 2.0 stia distruggendo qualcosa su cui si basa Clojure 1.3. Ho provato il più semplice esempio di codice che riesco a concepire in Grails 1.3.7, Groovy 1.8.4 (che è quello che usa Grails 2.0) e Groovy 1.8.5 (l'ultimo) e tutti funzionano. –

+3

Questo potrebbe essere un problema di ClassLoader? – Jeremy

risposta

4

Ho trovato un problema chiamato CLJ-944 su clojure.org. Vi si possono trovare una soluzione per ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class problema

Il problema è:

che il compilatore inietta un cast non corretto per clojure.lang.PersistentHashMap. In questo caso dovrebbe probabilmente essere convertito in clojure.lang.Associative, la più alta interfaccia comune con il metodo .containsKey.

Patch 1-0001-Fix-for-CLJ-944.patch

Patch 2-0002-Fix-for-CLJ-944.patch

spero che aiuta.