Clojure 1.2.1 / 1.3 / 1.4 'proxy ที่สร้างใน Grails 2.0.0 runtime ล้มเหลว 1.2.0 ไม่เป็นไร


103

ผมทำงานเกี่ยวกับการขยายปลั๊กอิน Grails ClojureในGrails 2.0.0 (และ 2.1.0-ภาพนิ่ง) และฉันต้องการที่จะปรับปรุงมันClojure 1.3.0และเพิ่มclojure.tools.logging

Clojure แสดงข้อยกเว้นระหว่างการรวบรวม พร็อกซีของฟังก์ชันล็อกสตรีมของ a ByteArrayOutputStreamin clojure.tools.logging:

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

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

ฉันไปลบclojure.tools.loggingและเขียนพร็อกซีที่ถูกถอดออกของObject:

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

และมันก็โยนClassCastExceptionข้อความและข้อความนั้นออกไป

ฉันพยายามพิมพ์macroexpand-1ของพร็อกซีและได้รับสิ่งเดียวกัน

ฉันเปลี่ยนกลับเป็น Clojure 1.2.0 และพร็อกซีทำงานได้ดีอีกครั้ง

ฉันลองใช้จำนวน 1.4.0 และมีพฤติกรรมเช่นเดียวกับ 1.3.0 1.2.1 ยังมีข้อยกเว้นบางอย่าง แต่ฉันพยายามตี 1.3.0 ดังนั้นฉันจึงไม่ได้ใช้เวลากับมันมากนัก

สแต็คร่องรอยจุดที่ 'ฟังก์ชั่น GEN-วิธีการที่กำหนดไว้ในหนึ่งในช่วยให้รูปแบบของในgenerate-proxycore_proxy.clj

ฉันเพิ่มความรู้แค่หางอึ่งเล็กน้อยprintlnรอบ ๆ ที่นั่นเพื่อดูว่าฉันสามารถจับสิ่งที่เกิดขึ้นได้หรือไม่ บางทีข้อความต่อไปนี้อาจทรยศต่อความเข้าใจผิดอย่างมากของผู้อ่านในส่วนของฉัน แต่เพียงแค่เพิ่มสิ่งเหล่านั้นprintlnก็เปลี่ยนพฤติกรรมการรวบรวมเวลาในแบบที่ฉันไม่คาดคิดโดยสิ้นเชิง ตำแหน่งของข้อยกเว้นและประเภทข้อยกเว้นเปลี่ยนไปอย่างสมบูรณ์แม้ว่าการทดสอบ Clojure ทั้งหมดmvn packageจะยังคงผ่านไป

ตัวอย่างเช่นเพียงแค่เพิ่ม single printlnto gen-method ก่อนที่จะเริ่มสร้าง bytecode ทำให้ Clojure โยน

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

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

ผมเคยเห็นข้อผิดพลาดอื่น ๆ อีกมากมายขึ้นอยู่กับที่ผมใส่println(s) แต่นี้เป็นที่แพร่หลายมากที่สุด

เห็นได้ชัดว่าบางส่วนของ Grails และ Clojure ไม่ได้เชื่อมต่อกันอย่างถูกต้องที่นี่ แต่ฉันไม่เห็นความเชื่อมโยง ตอนแรกฉันสงสัยว่า ASM เข้ากันไม่ได้ แต่เนื่องจาก Clojure มีเนมสเปซ ASM ของตัวเองฉันจึงไม่เห็นว่าเป็นปัญหา แต่บางทีฉันผิดฉันได้รับการจ้องมองที่clojure.lang.Compiler, พร็อกซี่และสร้าง-พร็อกซีสำหรับวันตอนนี้พยายามที่จะได้รับนี้ในการทำงานและฉันได้หยุดสวยมากทำให้มีความคืบหน้าไปข้างหน้าเพราะผมเคยทำงานออกจากไอน้ำ :(

ฉันขอโทษที่ไม่มีลิงค์ คุณสามารถคัดลอกและวางได้จากด้านล่าง:

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บรรทัด 133 คือ 'proxy


4
ฉันได้ทำการทดสอบเพิ่มเติมแล้วและฉันก็ทุกคน แต่เชื่อว่ามันมีบางอย่างใน Grails 2.0 ที่ทำลายสิ่งที่ Clojure 1.3 อาศัยอยู่ ฉันทดสอบตัวอย่างโค้ดที่ง่ายที่สุดที่ฉันสามารถตั้งครรภ์ได้ใน Grails 1.3.7, Groovy 1.8.4 (ซึ่งเป็นสิ่งที่ Grails 2.0 ใช้) และ Groovy 1.8.5 (ล่าสุด) และทั้งหมดนั้นใช้ได้ผล
John Courtland

3
นี่อาจเป็นปัญหา ClassLoader หรือไม่
Jeremy

คำตอบ:


4

ผมพบว่าปัญหาที่เรียกว่าCLJ-944ในclojure.org คุณจะพบวิธีแก้ไขClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Classปัญหาที่นั่น

ปัญหาคือ:

ที่คอมไพลเลอร์ฉีด cast ที่ไม่ถูกต้องไปยัง clojure.lang.PersistentHashMap ในกรณีนี้ควรส่งไปยัง clojure.lang.Associative ซึ่งเป็นอินเทอร์เฟซทั่วไปสูงสุดที่มีเมธอด .containsKey

แพทช์ 1 - 0001-Fix-for-CLJ-944.patch

แพทช์ 2 - 0002-Fix-for-CLJ-944.patch

ฉันหวังว่ามันจะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.