Proxy Clojure 1.2.1 / 1.3 / 1.4 'được tạo trong thời gian chạy Grails 2.0.0 không thành công. 1.2.0 là ổn


103

Tôi đang làm việc để mở rộng plugin Grails Clojure trong Grails 2.0.0 (và 2.1.0-SNAPSHOT) và tôi muốn cập nhật nó lên Clojure 1.3.0 và thêm clojure.tools.logging .

Clojure ném một ngoại lệ trong lập một ủy nhiệm của một ByteArrayOutputStreamtrong clojure.tools.logging's hàm log-stream:

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

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

Tôi đã gỡ bỏ clojure.tools.loggingvà viết một proxy bị tước bỏ của Object:

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

và nó cũng ném cùng một ClassCastExceptionthông điệp và thông điệp đó.

Tôi đã thử in macroexpand-1 của proxy và nhận được điều tương tự.

Tôi đã hoàn nguyên về Clojure 1.2.0 và proxy hoạt động tốt trở lại.

Tôi đã thử một số hóa thân của 1.4.0 và chúng thể hiện hành vi tương tự như 1.3.0. 1.2.1 cũng ném ra một số loại ngoại lệ nhưng tôi đang cố gắng đạt 1.3.0 nên tôi không dành nhiều thời gian cho điều đó.

Dấu vết ngăn xếp trỏ đến hàm 'gen-method được xác định ở một trong các dạng let of generate-proxyin core_proxy.clj.

Tôi đã thêm một vài mảnh nhỏ printlnxung quanh đó để xem liệu tôi có thể nắm bắt được những gì đang xảy ra hay không. Có thể tuyên bố tiếp theo này sẽ phản bội sự hiểu lầm lớn của người đọc về phía tôi nhưng chỉ cần thêm những câu đó printlnđã thay đổi hành vi thời gian biên dịch theo cách mà tôi hoàn toàn không mong đợi. Vị trí ngoại lệ và loại ngoại lệ hoàn toàn thay đổi, mặc dù tất cả các bài kiểm tra Clojure mvn packagevẫn tiếp tục vượt qua.

Ví dụ: chỉ cần thêm một đơn printlnvào gen-method ngay trước khi nó bắt đầu tạo bytecode khiến Clojure ném

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

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

Tôi đã thấy nhiều lỗi khác tùy thuộc vào nơi tôi đặt println(các) nhưng đây là lỗi phổ biến nhất.

Rõ ràng là một số khía cạnh của Grails và Clojure không được chia lưới một cách chính xác ở đây, nhưng tôi không thấy sự kết nối. Lúc đầu, tôi nghi ngờ sự không tương thích của ASM nhưng vì Clojure có không gian tên ASM của riêng nó, tôi không thể thấy đó là vấn đề. Nhưng có lẽ tôi sai, tôi đã nhìn chằm chằm vào clojure.lang.Compiler, ủy quyềntạo-proxy cho ngày nay cố gắng để có được điều này để làm việc và tôi đã khá nhiều dừng lại làm phía trước tiến bộ bởi vì tôi đã chạy ra khỏi hơi :(

Tôi xin lỗi vì thiếu liên kết. Bạn có thể sao chép và dán từ bên dưới:

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

Ghi nhật ký công cụ Clojure - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj dòng 133 là 'proxy


4
Tôi đã thực hiện thêm một số thử nghiệm và tôi tin rằng đó là thứ trong Grails 2.0 đang phá hỏng thứ mà Clojure 1.3 dựa vào. Tôi đã thử nghiệm mẫu mã đơn giản nhất mà tôi có thể hiểu được trong Grails 1.3.7, Groovy 1.8.4 (là những gì Grails 2.0 sử dụng) và Groovy 1.8.5 (mới nhất) và tất cả chúng đều hoạt động.
John Courtland

3
Đây có thể là sự cố ClassLoader?
Jeremy,

Câu trả lời:


4

Tôi đã tìm thấy Sự cố có tên CLJ-944trên clojure.org . Ở đó bạn có thể tìm thấy một sửa chữa cho ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Classvấn đề

Vấn đề là:

rằng trình biên dịch đưa một diễn viên không chính xác vào clojure.lang.PersistingHashMap. Trong trường hợp này, có lẽ nó nên được truyền sang clojure.lang.Associative, giao diện chung cao nhất có phương thức .containsKey.

Bản vá 1 - 0001-Fix-for-CLJ-944.patch

Bản vá 2 - 0002-Fix-for-CLJ-944.patch

Tôi hy vọng nó sẽ giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.