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

欢迎!有关如何使用本网站的更多信息,请参阅关于页面。

+2
用户头像 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"

经过一些尝试和错误,似乎是由于局部参数 i.e :some-keyword 导致的差异,在 clj-uuid/v5 函数中,它会将关键字对象转换为字节数组,这似乎现在是不同的。(如果我用字符串而不是关键字作为局部参数,则生成的 uuid 在 Clojure 升级前后都是一致的。)
生产的 uuids 用于下游系统,处理这些变化会相当困难。我能否以完全相同的方式获得之前的 uuids?

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

2 答案

0
用户头像

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

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

编辑

这里是记录从别处重提的对话 - 使用关键字作为名称的局部部分似乎会导致clj-uuid使用Java序列化将对象序列化为字节。

Clojure 1.11在Keyword(改进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局部名称部分使用更稳定的东西(如字符串)。

注意,我们将进行1.11.1版本,并将Keyword和ArraySeq的serialVersionUID重新固定到1.10.3版本。当然,这可能有助于决定推迟升级路径。
关于uuid的延迟升级路径,对此有何看法?强制使用一个非兼容但稳定的序列化作为可选或默认的方式吗?
我不认为有好的标准方式来处理这个问题,除了在库中标明兼容性说明。你可以使用版本条件 operand,但这些选项都很糟糕且会影响性能。
Clojure 1.11.1-rc1现已发布 - 请测试并反馈!
非常感谢,看起来很好!
...