在Grails 2.0.0运行时生成的Clojure 1.2.1 / 1.3 / 1.4代理失败。 1.2.0很好
我正在Grails 2.0.0 (和2.1.0-SNAPSHOT)中扩展Grails Clojure插件 ,我想将其更新到Clojure 1.3.0并添加clojure.tools.logging 。
在clojure.tools.logging
的日志stream函数中编译ByteArrayOutputStream
的代理时 ,Clojure抛出exception:
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的一些化身,它们performance出与1.3.0相同的行为。 1.2.1也会抛出一些exception,但是我正在尝试打1.3.0,所以我没有花太多时间。
堆栈跟踪指向core_proxy.clj
中generate-proxy
的letforms之一中定义的gen-method函数。
我在那里添加了一些println
的东西,看看能不能发现。 也许这下一个陈述将会泄露读者的一个巨大的误解,但只是添加这些println
改变了编译时间的行为,我完全没有想到的方式。 即使所有mvn package
的Clojuretesting都继续通过,exception位置和exceptiontypes也完全改变了。
例如,在开始生成字节码之前,只需要将一个println
添加到gen-method,就可以抛出Clojure
ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class
( https://gist.github.com/5a7a40929a6c4a104bd5 )
我已经看到了各种其他的错误,取决于我把println
(s)放在哪里,但这是最stream行的。
显然,Grails和Clojure的某些方面在这里没有正确的网格划分,但我没有看到连接。 起初我怀疑ASM不兼容,但是由于Clojure有自己的ASM命名空间,所以我不能看到这个问题。 但也许我错了,我一直在盯着clojure.lang.Compiler
, 代理和生成代理几天,现在试图让这个工作,我几乎停止前进的进展,因为我已经用完了蒸汽 :(
我对缺less链接表示抱歉。 你可以从下面复制和粘贴:
Grails Clojure – github.com/grails-plugins/grails-clojure
Clojure工具日志logging – github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj 133行是'proxy
我在clojure.org上发现了一个叫做CLJ-944
问题。 在那里你可以find一个解决ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class
问题
问题是:
编译器将不正确的转换注入到clojure.lang.PersistentHashMap。 在这种情况下,它应该被转换为clojure.lang.Associative,它是具有.containsKey方法的最高通用接口。
补丁1 – 0001-Fix-for-CLJ-944.patch
补丁2 – 0002-Fix-for-CLJ-944.patch
我希望它有帮助。