Clojure 2024 州调查中分享你的想法!

欢迎!有关本网站如何运作的更多信息,请参阅关于页面。

0投票
Java 互操作

补丁前

`
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (.f ^I p)

ClassCastException: user.proxy$java.lang.Object$I$383c225e 不能转换为 user.I (user$eval7491.invokeStatic (:1))
`

补丁后

`
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (.f ^I p)
1
`

原因: `proxy` 使用一组类名来缓存生成的类(查看https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_proxy.clj#L280-L286),这在接口重新定义下是不安全的

建议:更改用于确定代理类缓存命中的哈希函数,让它考虑每个接口/父类而不是仅仅是它们的名称

补丁: 0001-CLJ-2379-idempotent-proxy-name-just-on-identical-ins-v2.patch

6 答案

0投票

评论者:alexmiller

你能在描述中添加一条建议行解释更改吗?

0投票

评论者:alexmiller

我不确定我是否明白了这个问题/解决方案。

0投票

评论者:bronsa

当然,已完成

0投票
by

评论者:alexmiller

看起来这会破坏(虽然脆弱)clojure.test-clojure.java-interop/test-proxy-non-serializable中的序列化对象(参见CLJ-2204,CLJ-2330)。

0投票
by

评论者:bronsa

如#clojure-dev所述,附加补丁禁用脆弱的测试并恢复了proxy-name的确定性。

0投票
by
参考资料:https://clojure.atlassian.net/browse/CLJ-2379(由bronsa报告)
...