我正在扩展 Grails 2.0中的 Grails Clojure 插件(和2.1.0-SNAPSHOT) ,我想把它更新到 Clojure 1.3.0并添加 日志记录。
在编译
clojure.tools.logging
的 log-stream 函数中 ByteArrayOutputStream
的代理 :
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
和消息。
我试图打印 代理人的 宏展开 -1也得到了同样的结果。
我恢复到 Clojure 1.2.0,而 代理人又能正常工作了。
我尝试了许多1.4.0的化身,它们表现出与1.3相同的行为。 1.2.1也抛出了一些异常,但是我试图达到1.3.0,所以我没有花太多时间在这上面。
栈跟踪指向在 core_proxy.clj
中 generate-proxy
的 让形式之一中定义的‘ gen-method 函数。
我在那附近加了一点 println
,看看我能否捕捉到正在发生的事情。也许下一个声明会暴露出我对读者的巨大误解,但是简单地添加这些 println
改变了编译时的行为,这是我完全没有预料到的。异常位置和异常类型完全改变了,尽管 mvn package
中的所有 Clojure 测试都继续通过。
例如,只要在 gen-method 开始生成字节码之前向它添加一个 println
,就会导致 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行是‘代理’