Der in Grails 2.0.0 Runtime generierte Clojure 1.2.1 / 1.3 / 1.4'-Proxy schlägt fehl. 1.2.0 ist in Ordnung

103

Ich arbeite daran, das Grails Clojure-Plugin in Grails 2.0.0 (und 2.1.0-SNAPSHOT) zu erweitern, und wollte es auf Clojure 1.3.0 aktualisieren und clojure.tools.logging hinzufügen .

Clojure löst beim Kompilieren eines Proxys der Log-Stream-Funktion eines ByteArrayOutputStreamIn eine Ausnahme aus clojure.tools.logging:

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

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

Ich ging und entfernte clojure.tools.loggingund schrieb einen abgespeckten Proxy von Object:

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

und es warf auch das gleiche ClassCastExceptionund Nachricht.

Ich habe versucht, einen Macroexpand-1 des Proxys zu drucken und habe das Gleiche erhalten.

Ich kehrte zu Clojure 1.2.0 zurück und der Proxy funktionierte wieder einwandfrei .

Ich habe eine Reihe von Inkarnationen von 1.4.0 ausprobiert und sie zeigen das gleiche Verhalten wie 1.3.0. 1.2.1 löst auch eine Art Ausnahme aus, aber ich versuche, 1.3.0 zu erreichen, also habe ich nicht viel Zeit damit verbracht.

Die Stapelverfolgung verweist auf die Funktion 'gen-method', die in einer der let- Formen von generate-proxyin definiert ist core_proxy.clj.

Ich fügte ein paar kleine hinzu println, um zu sehen, ob ich mitbekommen konnte, was los war. Vielleicht verrät diese nächste Aussage meinerseits ein großes Missverständnis des Lesers, aber durch einfaches Hinzufügen dieser printlns wurde das Verhalten bei der Kompilierung auf eine Weise geändert, die ich überhaupt nicht erwartet hatte. Der Ausnahmeort und der Ausnahmetyp wurden vollständig geändert, obwohl alle Clojure-Tests mvn packageweiterhin bestanden wurden.

Wenn printlnClojure beispielsweise kurz vor dem Generieren des Bytecodes eine Single zur gen-Methode hinzufügt , wird Clojure ausgelöst

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

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

Ich habe verschiedene andere Fehler gesehen, je nachdem, wo ich die println(s) abgelegt habe, aber dies ist die häufigste.

Offensichtlich greifen einige Aspekte von Grails und Clojure hier nicht richtig ineinander, aber ich sehe den Zusammenhang nicht. Zuerst vermutete ich eine ASM-Inkompatibilität, aber da Clojure einen eigenen ASM-Namespace hat, kann ich nicht sehen, dass dies das Problem ist. Aber vielleicht bin ich falsch, ich habe an gestarrt clojure.lang.Compiler, Proxy und generieren-Proxy für Tage jetzt versuchen , dies zu Arbeit zu bekommen , und ich habe so ziemlich aufgehört, nach vornem Fortschritt , weil ich von Dampf ausgehen :(

Ich entschuldige mich für das Fehlen von Links. Sie können von unten kopieren und einfügen:

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

Protokollierung der Clojure-Tools - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj Zeile 133 ist der Proxy

John Courtland
quelle
4
Ich habe noch einige Tests durchgeführt und bin fast überzeugt, dass es etwas in Grails 2.0 ist, das etwas ruiniert, auf das sich Clojure 1.3 stützt. Ich habe das einfachste Codebeispiel getestet, das ich mir in Grails 1.3.7, Groovy 1.8.4 (das ist, was Grails 2.0 verwendet) und Groovy 1.8.5 (das neueste) vorstellen kann, und alle funktionieren.
John Courtland
3
Könnte dies ein ClassLoader-Problem sein?
Jeremy

Antworten:

4

Ich habe ein ProblemCLJ-944 auf clojure.org gefunden . Dort finden Sie eine Lösung für das ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.ClassProblem

Das Problem ist:

dass der Compiler eine falsche Umwandlung in clojure.lang.PersistentHashMap einfügt. In diesem Fall sollte es wahrscheinlich in eine clojure.lang.Associative umgewandelt werden, die höchste gemeinsame Schnittstelle mit der .containsKey-Methode.

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

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

Ich hoffe, es hilft.

Sentencio
quelle