Serwer proxy Clojure 1.2.1 / 1.3 / 1.4 wygenerowany w środowisku wykonawczym Grails 2.0.0 nie działa. 1.2.0 jest w porządku

103

Pracuję nad rozszerzeniem wtyczki Grails Clojure w Grails 2.0.0 (i 2.1.0-SNAPSHOT) i chciałem zaktualizować ją do Clojure 1.3.0 i dodać clojure.tools.logging .

Clojure zgłasza wyjątek w trakcie zestawiania a proxy się z A ByteArrayOutputStreamw clojure.tools.logging„s Funkcja rejestru strumienia:

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

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

Poszedłem i usunięte clojure.tools.loggingi napisał uproszczoną proxy z Object:

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

a także rzucił to samo ClassCastExceptioni przesłanie.

Próbowałem wydrukować macroexpand-1 z proxy i dostał to samo.

Wróciłem do Clojure 1.2.0 i proxy znowu działało dobrze.

Wypróbowałem kilka wcieleń wersji 1.4.0 i wykazują one takie samo zachowanie jak 1.3.0. 1.2.1 również rzuca jakiś wyjątek, ale próbuję trafić 1.3.0, więc nie spędziłem z tym dużo czasu.

Śledzenie stosu wskazuje na funkcję „gen-method” zdefiniowaną w jednej z form letgenerate-proxy in core_proxy.clj.

Dodałem trochę informacji, printlnżeby zobaczyć, czy uda mi się złapać, co się dzieje. Może to następne stwierdzenie zdradzi ogromne nieporozumienie czytelnika z mojej strony, ale zwykłe dodanie tych printlnznaków zmieniło zachowanie czasu kompilacji w sposób, którego całkowicie się nie spodziewałem. Lokalizacja wyjątku i typ wyjątku całkowicie się zmieniły, mimo że wszystkie testy Clojure mvn packagenadal przechodzą.

Na przykład, dodanie pojedynczego printlndo metody gen tuż przed rozpoczęciem generowania kodu bajtowego spowodowało, że Clojure wyrzucił

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

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

Widziałem różne inne błędy w zależności od tego, gdzie umieściłem println(s), ale jest to najbardziej rozpowszechnione.

Oczywiście niektóre aspekty Grails i Clojure nie zazębiają się tutaj poprawnie, ale nie widzę związku. Na początku podejrzewałem niezgodność ASM, ale ponieważ Clojure ma własną przestrzeń nazw ASM, nie widzę tego problemu. Ale może się mylę, byłem wpatrując się clojure.lang.Compiler, proxy i generować-proxy dla dni teraz stara się uzyskać to do pracy, a ja prawie przestali robić postęp do przodu, bo zabrakło pary :(

Przepraszam za brak linków. Możesz skopiować i wkleić od dołu:

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

Rejestrowanie narzędzi Clojure - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj wiersz 133 to „proxy

John Courtland
źródło
4
Zrobiłem więcej testów i jestem prawie przekonany, że jest to coś w Grails 2.0, co niszczy coś, na czym polega Clojure 1.3. Przetestowałem najprostszy kod, jaki mogę sobie wyobrazić, w Grails 1.3.7, Groovy 1.8.4 (którego używa Grails 2.0) i Groovy 1.8.5 (najnowszy) i wszystkie działają.
John Courtland,
3
Czy może to być problem ClassLoader?
Jeremy

Odpowiedzi:

4

Znalazłem problem nazwany CLJ-944na clojure.org . Tam możesz znaleźć rozwiązanie ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Classproblemu

Problemem jest:

że kompilator wstrzykuje niepoprawne rzutowanie do clojure.lang.PersistentHashMap. W tym przypadku powinien on być prawdopodobnie rzutowany na clojure.lang.Associative, najwyższy wspólny interfejs z metodą .containsKey.

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

Łatka 2 - 0002-Fix-for-CLJ-944

Mam nadzieję, że to pomoże.

Sentencio
źródło