Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the cross-building convention append the scala version to the artifactId?

Tags:

maven

sbt

The underlying mechanism used to indicate which version of Scala a library was compiled against is to append _<scala-version> to the library's name. This fairly simple approach allows interoperability with users of Maven, Ant and other build tools. -- sbt Documentation: Cross-Build Publishing Conventions

While this is a simple approach, the interoperability with Maven and other build tools leaves something to be desired. Because the artifactId is different (e.g. scalatest_2.9.0 and scalatest_2.10.0), Maven treats them as different artifacts. Maven's dependency resolution mechanism is thus compromised and multiple versions of the same artifact (built against different scala versions) can wind up on the classpath.

Why not put the scala version in the classifier? This seems to be one of the primary intended use cases for the classifier:

The classifier allows [Maven] to distinguish artifacts that were built from the same POM but differ in their content. As a motivation for this element, consider for example a project that offers an artifact targeting JRE 1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the second one with jdk14 such that clients can choose which one to use. -- Maven Documentation: POM Reference

like image 986
oby1 Avatar asked Apr 16 '14 23:04

oby1


1 Answers

Appending version to the name is a historical decision that was made long time ago so it'll likely not going to change since many libraries are published with the convention already.

Having said that, as Seth noted, there was a discussion to review this topic a few years ago when sbt 0.12 shortened "_2.10.0" postfix to "_2.10" to take advantage of Scala library's binary compatibility between the minor versions. Here's Mark from [0.12] plan:

By cross versioning, I mean the practice of including some part of the Scala version in the module ID to distinguish an artifact generated by compiling the same source code against different Scala versions. I do not mean the ability to build against multiple Scala versions using +task, which will stay; I am just referring to the cross version convention.

[snip]

It has always been a hack to encode this in the inflexible pom.xml format and I think it may be best to move away from this for projects built against Scala 2.10 and later. However, perhaps this is better than any ad hoc solutions that might take its place. I don't see users of other build tools doing this, so I expect nothing would replace it.

Somewhere down the thread Josh suggested:

(1) Scala classifiers. These can be custom strings and can be specified with dependencies. At least, IIRC this should work.

Here's Mark's response:

What do mean by "can be specified with dependencies"? There is only one pom for all of the classifiers, right? How can you declare different dependencies for each classifier?

Here are some more interesting remark on classifiers from Geoff Reedy

I too thought that classifiers would be the perfect way to deal with this issue especially in light of the suggestion in the maven docs that classifiers java-1.4 and java-1.5 be used to distiguish between jars appropriate for the respective platform. The fatal flaw seems to be transitive dependency management. That is, there's no way to choose the transitive dependency set based on the classifier used to require the module. We'd need to be able to say that when you're using this module with the scala-2.10 classifier it brings its own dependencies using the scala-2.10 classifier and when used with the 2.9 classifier brings in its own deps with the scala-2.9 classifier.

I think with the jvm versions it's possible to make this work because jvm versioning has special support in the profile activation which can can control dependencies.

like image 74
Eugene Yokota Avatar answered Sep 25 '22 08:09

Eugene Yokota