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

欢迎!请查看关于页面了解更多关于此如何工作的信息。

+2
Clojure
已关闭

嗨,我在升级到Clojure 1.11.0时遇到了以下情况。在我们应用程序中,我们在某些地方创建V5(基于名称,SHA1散列)UUID,使用danlentz/clj-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中修复

2个答案

0

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

by
是的,相同的Java版本(openjdk version "17.0.2")
0
by
修改 by

在这里重提别处已经开始的对话,以作记录——使用一个关键字作为名称的局部部分似乎会导致clj-uuid使用Java序列化将对象序列化为字节。

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

我们不保证在不同版本之间Clojure对象的二进制可序列性,因此这里预期它们将是相同的是不正确的。如果希望,有几种在clj-uuid中解决这个问题的方式——通过在UUIDNameBytes协议中为关键字提供自定义序列化(https://github.com/danlentz/clj-uuid/blob/master/src/clj_uuid.clj#L557),或者依赖pr到字符串然后再到字节,而不是将对象流的二进制序列化等。

我们可能可以通过将clojure.lang.Keyword的serialversionUID设置为1.10中的值来“修复”这个特定的案例(因为这些对象可能具有二进制兼容性),并将考虑这一点。但是即使我们这样做,我仍建议使用更稳定的字符串作为clj-uuid本地名称部分。

by
FYI,我们计划进行1.11.1版本,并将Keyword和ArraySeq的serialVersionUIDs锁定在1.10.3版本。以防这有助于决定延迟升级路径。
by
关于 uuid 的延迟升级路径,大家对此有何看法?强制采用不兼容但稳定的序列化方式作为可选方案?默认设置如何?
by
我认为除了在库中放置兼容性说明外,没有很好的处理方式。你可以使用版本条件进行操作,但这些选项都很糟糕,会影响性能。
by
Clojure 1.11.1-rc1 已发布 - 请测试并反馈!
by
非常感谢,看起来不错!
...