2024 Clojure 状态调查! 中分享你的想法。

欢迎!请查看 关于 页面以了解更多此页面如何运作的信息。

0
Java Interop
已有两名用户报告,Clojure 1.10 中通过 clojure.reflect 返回的协议元添加引起的回归问题。

最短的复现可能如下


(require 'clojure.reflect)
(eval `~(clojure.reflect/reflect String))

;; 执行错误 (IllegalArgumentException) 出现在 user$eval9/<clinit> (REPL:1)。
;; 没有找到与类 clojure.reflect$typesym$fn__11946 匹配的构造函数

ExceptionInInitializerError
    sun.reflect.NativeConstructorAccessorImpl.newInstance0 (NativeConstructorAccessorImpl.java:-2)
    sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45)
    java.lang.reflect.Constructor.newInstance (Constructor.java:423)
    java.lang.Class.newInstance (Class.java:442)
    clojure.lang.Compiler$ObjExpr.eval (Compiler.java:4996)
    clojure.lang.Compiler.eval (Compiler.java:7175)
    clojure.lang.Compiler.eval (Compiler.java:7131)
    clojure.core/eval (core.clj:3214)
    clojure.core/eval (core.clj:3210)
    user/eval7 (NO_SOURCE_FILE:1)
    user/eval7 (NO_SOURCE_FILE:1)
原因
IllegalArgumentException 没有找到与类 clojure.reflect$typesym$fn__11946 匹配的构造函数
    clojure.lang.Reflector.invokeConstructor (Reflector.java:288)
    clojure.lang.LispReader$EvalReader.invoke (LispReader.java:1317)
    clojure.lang.LispReader$DispatchReader.invoke (LispReader.java:853)
    clojure.lang.LispReader.read (LispReader.java:285)
    clojure.lang.LispReader.read (LispReader.java:216)
    clojure.lang.LispReader.read (LispReader.java:205)
    clojure.lang.RT.readString (RT.java:1878)
    clojure.lang.RT.readString (RT.java:1873)
    user/eval9 (NO_SOURCE_FILE:1)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0 (NativeConstructorAccessorImpl.java:-2)
    sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62)


实际发生这种情况的案例包括宏返回值中使用的 clojure.reflect (请参阅 https://groups.google.com/forum/#!msg/clojure/pxLN9tYti4c/zbhLCOrTBgAJ 的一个示例)。

原因:现在从 clojure.reflect 返回的类符号被添加了元信息,例如


#:clojure.core.protocols{datafy #object[clojure.reflect$typesym$fn__11946 0x49fc609f "clojure.reflect$typesym$fn__11946@49fc609f"]}


这包含一个嵌入的数据化函数。编译器将此放入编译类池(用 MetaExpr 包装的对象)。

冲突解决:一种解决方法是剥离宏内部符号的元信息并返回被剥离的符号。

1 个回答

0
参考:https://clojure.atlassian.net/browse/CLJ-2494(由 alexmiller 报告)
...