请在2024 Clojure状态调查中分享您的想法!

欢迎!请查看关于页面以获取更多工作原理信息。

0
编译器
关闭

使用 core/proxy 为 Java 类生成代理时,生成的类文件中产生不可预测的方法顺序。
这对于可重复构建(在执行 AOT 时)来说是一个问题。

具体来说,我正在 Docker 中运行 Clojure,并且希望我的应用程序镜像层与 Java 开发者生成的尽可能小(使用 Meta-inf 类路径和 lib 目录)。无论如何,为了正确地工作,以便所有依赖项(包括作为 AOT 部分编译的依赖项)都在一个单独的层上,我需要每次构建时编译我的应用程序依赖项代理的输出都相同。这减少了构建时间、镜像推送时间、镜像拉取时间和容器调度时间。

展示问题的示例代码(您需要运行几次才能看到问题)。

https://github.com/kipz/predictable-proxies

原因:我已经将它追踪到此处使用未排序的映射

https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_proxy.clj#L186

方法:使用按键的哈希值排序的映射(键是一个方法名、参数类型的序列和返回类型的向量)。

补丁:CLJ-1973-v5.patch

审核者:Alex Miller

带注释关闭:发布在 1.11.0-beta1 中

10 个答案

0

评论者:kipz

使用 sorted-map 的补丁

0

评论者:alexmiller

我认为你可以遵循https://clojure.org/guides/comparators上的建议来为这个补丁编写一个更简单的比较器。

0

评论者:kipz

如请求,提供了一个更简单的比较器。

0

评论者:alexmiller

我认为你失去了排序后的集合。

0

评论者:kipz

分支间复制粘贴错误。这次已测试。

0

评论者:kipz

现在对'let'的格式化更一致了

0

评论者:alexmiller

虽然这可能是可以的,但可能最好使用Clojure的'hash'函数而不是Java的'hashCode'函数。映射本身是基于hash计算的,这看起来更合适。

0

评论者:kipz

如您请求,使用了Clojure的'hash'。

谢谢Alex - 也学习了布尔比较器!

0

评论者:alexmiller

请注意,这种顺序可能还会因 Clojure 或 JVM 版本的变化而有所不同,因为这些版本之间没有保证可靠的哈希值。目前进行预筛选。

0
参考资料:https://clojure.atlassian.net/browse/CLJ-1973(由 kipz 报告)
...