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


103

Sto lavorando all'estensione del plugin Grails Clojure in Grails 2.0.0 (e 2.1.0-SNAPSHOT) e volevo aggiornarlo a Clojure 1.3.0 e aggiungere clojure.tools.logging .

Clojure genera un'eccezione durante la compilazione di una delega di un ByteArrayOutputStreamin clojure.tools.loggingfunzione di log-stream 's:

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

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

Sono andato e ho rimosso clojure.tools.logginge ho scritto un proxy ridotto di Object:

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

e ha anche lanciato lo stesso ClassCastExceptionmessaggio e.

Ho provato a stampare una macroexpand-1 del proxy e ho ottenuto la stessa cosa.

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

Ho provato una serie di incarnazioni della 1.4.0 e mostrano lo stesso comportamento della 1.3.0. 1.2.1 genera anche una sorta di eccezione, ma sto cercando di raggiungere 1.3.0, quindi non ci ho passato molto tempo.

Lo stack trace punta alla funzione 'gen-method definita in una delle forme let di generate-proxyin core_proxy.clj.

Ho aggiunto una piccola infarinatura di printlnlaggiù per vedere se riuscivo a capire cosa stava succedendo. Forse questa prossima affermazione tradirà un enorme malinteso del lettore da parte mia, ma la semplice aggiunta di questi ha printlncambiato il comportamento in fase di compilazione in un modo che non mi aspettavo. La posizione dell'eccezione e il tipo di eccezione sono completamente cambiati, anche se tutti i test di Clojure mvn packagecontinuano a passare.

Ad esempio, l'aggiunta di un singolo printlnmetodo a gen subito prima che inizi a generare bytecode ha causato il lancio di Clojure

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

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

Ho visto vari altri errori a seconda di dove metto il println/ i ma questo è il più diffuso.

Ovviamente alcuni aspetti di Grails e Clojure non si adattano correttamente qui, ma non vedo la connessione. All'inizio sospettavo l'incompatibilità ASM, ma poiché Clojure ha il proprio spazio dei nomi ASM, non vedo che sia questo il problema. Ma forse mi sbaglio, sto fissando clojure.lang.Compiler, di proxy e generare proxy da giorni cercando di ottenere questo al lavoro e ho praticamente smesso di fare avanti progredire perché ho corto di vapore :(

Mi scuso per la mancanza di link. Puoi copiare e incollare da sotto:

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

Clojure Tools Logging - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj la riga 133 è il 'proxy


4
Ho fatto altri test e sono quasi convinto che sia qualcosa in Grails 2.0 che sta distruggendo qualcosa su cui si basa Clojure 1.3. Ho testato l'esempio di codice più semplice che posso concepire in Grails 1.3.7, Groovy 1.8.4 (che è quello che utilizza Grails 2.0) e Groovy 1.8.5 (l'ultimo) e funzionano tutti.
John Courtland

3
Potrebbe essere un problema di ClassLoader?
Jeremy

Risposte:


4

Ho trovato un problema chiamato CLJ-944su clojure.org . Lì puoi trovare una soluzione per il ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Classproblema

Il problema è:

che il compilatore inserisce un cast errato in clojure.lang.PersistentHashMap. In questo caso dovrebbe probabilmente essere eseguito il cast su clojure.lang.Associative, l'interfaccia comune più alta con il metodo .containsKey.

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

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

Spero possa essere d'aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.