欢迎!请参见关于页面以了解更多有关如何使用本网站的信息。
使用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 核对
由kipz发布评论:
使用sorted-map补丁
评论者:alexmiller
我认为您可以按照https://clojure.org/guides/comparators中的建议来为这个补丁编写一个更简单的比较器。
按照要求完成了更简单的比较器。
我认为您丢失了排序好的集合。
在不同分支之间复制粘贴错误。这次已测试。
现在有了更一致的 'let' 格式。
虽然这可能是可以的,但或许最好使用Clojure的 hash 函数而不是 Java 的 .hashCode 函数。映射本身是基于 hash 进行哈希的,因此这似乎更合适。
按照要求,现在使用 Clojure 的 'hash' 函数。
感谢Alex - 还学到了布尔比较器!
请注意,这种排序可能在不同版本的Clojure或JVM之间仍可能发生变化,因为这些没有保证跨版本的哈希。目前进行预筛选。