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

欢迎!请参阅关于页面以了解更多关于此工作方式的信息。

+2
Clojure
已关闭

嗨,当更新到Clojure 1.11.0时,我遇到了以下情况。在我们的应用程序中,我们有一些地方使用danlentz/clj-uuid库创建V5(基于名称,SHA1散列)uuids。在升级后,产生的v5 uuids不同。例如

(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中,它将关键字Object转换为一个byte数组,现在看起来有所不同。(如果我用String代替关键字作为本地部分参数,则生成的uuid在Clojure升级前后是一致的。)
生成的uuids被用于下线系统,要处理这种变化会相当困难。我能否以任何方式生成与之前完全相同的uuids?

注:已经修复在1.11.1

2 个答案

0

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

是的,相同的Java版本(openjdk版本 "17.0.2")
0

编辑了

这里只是为了记录,重新从别处开始这段对话 - 使用关键词作为名称局部部分似乎会导致clj-uuid使用Java序列化将对象序列化为字节。

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

我们不保证Clojure对象在不同版本之间的二进制可序列性,因此这里期望它们应该是相同的这个预期是不正确的。在clj-uuid中,有几种方法可以实现这个特性,如果需要的话,例如通过对Keyword具体在UUIDNameBytes协议中提供自定义序列化(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
非常感谢,看起来不错!
...