Proksi Clojure 1.2.1 / 1.3 / 1.4 'yang dibuat di runtime Grails 2.0.0 gagal. 1.2.0 baik-baik saja

103

Saya sedang mengembangkan plugin Grails Clojure di Grails 2.0.0 (dan 2.1.0-SNAPSHOT) dan saya ingin memperbaruinya ke Clojure 1.3.0 dan menambahkan clojure.tools.logging .

Clojure melempar pengecualian selama kompilasi dari proksi dari ByteArrayOutputStreamdalam clojure.tools.loggingfungsi log-aliran 's:

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

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

Saya pergi dan menghapus clojure.tools.loggingdan menulis proxy yang dilucuti dari Object:

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

dan itu juga ClassCastExceptionmenyampaikan pesan dan pesan yang sama .

Saya mencoba mencetak macroexpand-1 dari proxy dan mendapatkan hal yang sama.

Saya kembali ke Clojure 1.2.0 dan proxy berfungsi dengan baik lagi.

Saya mencoba sejumlah inkarnasi 1.4.0 dan mereka menunjukkan perilaku yang sama dengan 1.3.0. 1.2.1 juga memberikan semacam pengecualian tetapi saya mencoba untuk mencapai 1.3.0 jadi saya tidak menghabiskan banyak waktu dengan itu.

Jejak tumpukan menunjuk ke fungsi 'gen-method yang didefinisikan di salah satu bentuk biarkangenerate-proxy masuk core_proxy.clj.

Saya menambahkan sedikit printlndi sekitar sana untuk melihat apakah saya bisa menangkap apa yang terjadi. Mungkin pernyataan berikut ini akan mengkhianati kesalahpahaman besar pembaca di pihak saya, tetapi menambahkannya saja telah printlnmengubah perilaku waktu kompilasi dengan cara yang sama sekali tidak saya duga. Lokasi pengecualian dan jenis pengecualian benar-benar berubah, meskipun semua pengujian Clojure mvn packageterus berhasil.

Misalnya, hanya menambahkan satu printlnke gen-method tepat sebelum ia mulai menghasilkan bytecode menyebabkan Clojure terlempar

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

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

Saya telah melihat berbagai kesalahan lain tergantung di mana saya meletakkannya, printlntetapi ini yang paling umum.

Jelas beberapa aspek dari Grails dan Clojure tidak terhubung dengan benar di sini, tapi saya tidak melihat hubungannya. Awalnya saya curiga ASM tidak kompatibel, tetapi karena Clojure memiliki namespace ASM sendiri, saya tidak dapat melihat masalahnya. Tetapi mungkin saya salah, saya telah menatap clojure.lang.Compiler, proxy dan menghasilkan-proxy selama berhari-hari sekarang mencoba untuk membuat ini bekerja dan saya sudah cukup banyak berhenti membuat kemajuan karena saya kehabisan tenaga :(

Saya minta maaf atas kurangnya tautan. Anda dapat menyalin dan menempel dari bawah:

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

Pencatatan Alat Clojure - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj baris 133 adalah 'proxy

John Courtland
sumber
4
Saya telah melakukan beberapa pengujian lagi dan saya yakin itu adalah sesuatu di Grails 2.0 yang merusak sesuatu yang diandalkan Clojure 1.3. Saya menguji sampel kode paling sederhana yang dapat saya bayangkan di Grails 1.3.7, Groovy 1.8.4 (yang digunakan Grails 2.0) dan Groovy 1.8.5 (terbaru) dan semuanya berfungsi.
John Courtland
3
Mungkinkah ini masalah ClassLoader?
Jeremy

Jawaban:

4

Saya menemukan Masalah yang disebut CLJ-944di clojure.org . Di sana Anda dapat menemukan perbaikan untuk ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Classmasalah tersebut

Masalahnya adalah:

bahwa compiler memasukkan cast yang salah ke clojure.lang.PersistentHashMap. Dalam hal ini mungkin harus dilemparkan ke clojure.lang.Associative, antarmuka umum tertinggi yang memiliki metode .containsKey.

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

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

Saya harap ini membantu.

Sentencio
sumber