由于Scala版本之间仅具有源代码兼容性,因此您不得不为其支持的每个scala版本编译scalatest或scalamock等库。让我感到困惑的是,这些库提供了大量的工件(scalatest_2.9.0,scalatest_2.9.1,scalatest_2.10等等) - 每个scala版本都有一个,这样maven存储库中就堆满了许多由人工制作的文物。相同的来源。我的直觉告诉我宁愿为每个scala版本使用一个带有分类器的工件。 (事实上,maven pom reference提到这有时用jdk14和jdk15分类器来完成工件,这看起来与我相似。)那么,为什么Scala人会去寻找许多神器矫枉过正:-)而不是? / p>
答案 0 :(得分:5)
我可能错了,但如果分类器的目的是“区分由同一个POM构建但内容不同的工件”,那么我认为不使用它们的原因非常充分对于scala版本控制:scala版本不只是二进制不兼容,它们很可能源不兼容。 例如,当将scala从2.7升级到2.8时,我不得不对代码库进行一些重大更改。如果我想同时保留scala 2.7和2.8版本,我需要创建一个并行分支,并且两个分支肯定不会有相同的源代码。
当我读“来自同一个POM”时,我理解它也意味着来自相同的源代码,这显然不是这两个代码分支的情况。
另一个更重要的原因是分类器本质上是一个单独的字符串,已经用于许多事情。或多或少的标准分类器包括“源”,“javadoc”或“资源”。这些分类器的含义在scala项目中是相同的,并且与scala版本完全正交,我将尝试显示。
Maven的文档建议使用诸如“jdk15”或“jdk14”之类的分类符来表示编译二进制工件的jvm的哪个版本。 鉴于java代码是向后兼容的,原则上具有两个分类器(“jdk15”或“jdk14”)的工件是从相同的源代码编译的。这就是为什么你不需要复制“sources”工件的分类器,换句话说你不需要一个名为“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构建生态系统中进行更好集成。
答案 1 :(得分:2)
Scala仅在补丁版本(Major.Minor.Patch版本规范的第三个组件)中提供其字节码输出(.class
文件)的版本间兼容性。
Maven无法将其正确编码为工件的第一类属性,因此必须按名称中的约定进行编码。
...可悲