12

由于您在Scala版本之间只有源代码兼容性,因此不幸的是,您需要为它们支持的每个 scala 版本编译像scalatestscalamock这样的库。让我感到困惑的是,这些库提供了大量的工件(scalatest_2.9.0、scalatest_2.9.1、scalatest_2.10 等等)——每个 scala 版本都有一个,因此 maven 存储库中到处都是从构建的工件相同的来源。我的直觉告诉我宁愿为每个 scala 版本使用一个带有分类器的工件。(其实maven pom参考提到这有时是用 jdk14 和 jdk15 分类器来完成的,这似乎和我很相似。)那么,为什么 Scala 的人选择了许多工件过度杀伤 :-) 呢?

4

2 回答 2

5

我可能是错的,但如果分类器的目的是“区分由相同 POM 构建但内容不同的工件”,那么我认为有一个很好的理由将它们用于 scala 版本控制:scala 版本不仅仅是二进制不兼容,它们很可能是源不兼容的。例如,当将 scala 从 2.7 升级到 2.8 时,我必须对代码库进行一些重大更改。如果我想同时保留 scala 2.7 和 2.8 版本,我需要创建一个并行分支,并且两个分支肯定不会有相同的源代码。

当我读到“来自同一个 POM”时,我明白它也意味着来自同一个源代码,这显然不是这两个代码分支的情况。

另一个更重要的原因是分类器本质上是一个字符串,它已经用于许多事情。或多或少的标准分类器包括“sources”、“javadoc”或“resources”。这些分类器的含义在 scala 项目中是相同的,并且与 scala 版本完全正交,正如我将尝试展示的那样。

Maven 的文档建议使用诸如“jdk15”或“jdk14”之类的分类器来表示编译二进制工件的 jvm 版本。鉴于 java 代码是向后兼容的,原则上具有两个分类器(“jdk15”或“jdk14”)的工件是从相同的源代码编译的。这就是为什么您不需要为“源”工件复制分类器的原因,或者换句话说,您不需要需要有一个名为“sources-jdk14”和“sources-jdk15”的分类器。但是你不能对 scala 版本应用相同的理由:假设你可能需要不同的源代码,无论你是针对 scala 2.7 还是 scala 2.8 编译,你确实需要两个不同的带有分类器的工件,例如“sources-scala2.7”或“源-scala2.8"。所以我们已经有了复合分类器。至于二进制工件,您不仅需要区分目标 jvm 版本(请记住,您可以编译 scala 代码以针对不同的 jvm 版本),还需要区分编译它的 scala 版本。所以你最终会得到类似“jdk14-scala2.7”或“jdk14-scala2.8”或“jdk15-scala2.7”或“jdk15-scala2.8”的东西。还有一组复合分类器。所以带回家的信息是,scala 版本确实是一种对工件进行分类的单独方法,它与所有现有的分类器完全正交。是的,我们真的可以像上面那样使用复合分类器(例如“sources-scala2.7”),但是我们不会使用标准分类器,这本身就很混乱,但还需要修改分类器周围的所有工具:如果我使用不了解 scala(仅 java)但知道如何自动发布“源”工件的构建工具怎么办?我是否需要修改此构建工具,以便他知道要发布“sources-scala2.7”工件?另一方面,如果我在(基本)工件名称中编码 scala 版本并将其提供给构建工具,一切都会照常工作,我会得到一个带有“源”的工件

总而言之,与直接的直觉相反,在名称中编码 scala 版本可以更好地集成到现有的 java 构建生态系统中。

于 2013-02-27T09:20:39.777 回答
2

Scala 仅在补丁版本(Major.Minor.Patch 版本规范的第三个组件)之间提供其字节码输出(.class文件)的版本间兼容性。

Maven 没有地方将其正确编码为工件的一等属性,因此必须按照名称中的约定对其进行编码。

可悲...

于 2013-02-26T21:02:10.497 回答