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

欢迎!请参阅关于页面了解如何使用本网站的一些更多信息。

你好,我在更新到 Clojure 1.11.0 时遇到了以下问题。在我们的应用程序中,我们有一些使用 danlentz/clj-uuid 库来创建 V5(基于名称,SHA1 哈希)uuid 的地方。升级后,生成的 v5 uuid 不同。一个例子是:

(def ^:const +namespace+ #uuid "50d94d91-a1cf-422d-9586-4ddacf6df176")

(clj-uuid/v5 +namespace+ :some-keyword) 

;; Clojure 1.10.3
=> #uuid "d30e9c3c-ced2-534e-a6b8-ecf784fb0785"

;; Clojure 1.11.0
=> #uuid "a16f6719-952a-55b9-b71b-b15dd263665b"

经过一番尝试和错误,似乎是由于局部部分参数,即:some-keyword造成了差异,因为 clj-uuid/v5 函数将关键字对象转换为字节序列,现在看起来似乎不同了。(如果我用一个字符串而不是关键字作为局部部分参数,生成的 uuid 在 Clojure 升级前后是一致的。)
生成的 uuid 被用于下游系统,要让他们处理这种变化会非常困难。是否有办法能够生成与之前完全相同的 uuid 呢?

已关闭,备注:1.11.1 中已修复

你好。感谢您的报告。为了澄清——测试之间使用的 Java 版本相同,对吗?

是的,同样的 Java 版本(openjdk version "17.0.2")

编辑

此地为记录,这里只是重复在其他地方发生的对话 - 使用名称部分的关键字将导致 clj-uuid 使用 Java 序列化将对象 序列化为字节。

Clojure 1.11 对 Keyword 进行了一些增量且向后兼容的更改(以改进算术异常报告),因此关键字之间的二进制序列化在 1.10 和 1.11 之间发生了变化。

我们不保证 Clojure 对象在版本之间的二进制可序列性,因此这里对这些应该是相同的期望是不正确的。在 clj-uuid 中,如果需要,有多种方式可以解决此属性 - 在 UUIDNameBytes 协议中为 Keyword 提供自定义序列化 (https://github.com/danlentz/clj-uuid/blob/master/src/clj_uuid.clj#L557),或者在字符串到字节序列化与对象流之间的序列化等方面依赖 pr。

我们可能可以通过将 clojure.lang.Keyword 的 serialversionUID 设置为在 1.10 中存在的值来解决此特定情况(因为这些对象可能是二进制兼容的),我们将会考虑这一点。但即使我们这样做,我也建议使用更稳定的字符串为 clj-uuid 本地名称部分。

仅供参考,我认为我们将要做 1.11.1 版本,并将 Keyword 和 ArraySeq 的 serialVersionUIDs 锁定回 1.10.3 版本。希望这有助于决定延迟升级路径。
by
关于uuid的延期升级路径,有没有任何关于如何处理此问题的看法?是否强制使用不兼容(但稳定)的序列化作为可选或默认?
by
我认为除了在库上放置兼容性说明外,没有好的标准方法来处理这个问题。你可以使用版本条件语句做些事情,但这些选择都很糟糕,会影响性能。
by
Clojure 1.11.1-rc1现在已可用 - 请进行测试并报告!
by
非常感谢,看起来不错!
...