Let's say I'm writing a Scala library L that depends on some dependency D and is consumed by a program P and another program Q. P depends on version 3.2 of D directly while Q depends on version 3.3 directly.
Between those two versions D's API was shuffled so that to get the same function I use in L, I must write different import statements in L. Likewise P relies on 3.2-specific behavior whereas Q relies on 3.3-specific behavior.
Now, normally what will happen is that the most recent version of D will be chosen when compiling P and Q, but this will cause either P to break if L depends on version 3.3 of the library or L to break when compiling Q if L depends on version 3.2 of D.
I would ideally like the same version of L to be used by both P and Q since L's public API does not change. Is this possible?
The general method that comes to mind is conditional compilation of L based on dependency resolution. This seems unachievable though in the JVM world since we don't transitively compile a project's dependencies and instead rely on precompiled artifacts.
I can do this right now with SBT if D is Scala itself (i.e. cross-compiling with different Scala versions and having version specific code live in its own directories), but this is something of a hack from the viewpoint of dependency resolution since SBT changes the names of the artifacts to allow this cross-compilation to work.
You can tell sbt to handle dependencies as intransitive:
libraryDependencies ++= Seq(
"org.some.id" % "some-lib" % "1.0.foobar" intransitive()
)
would add some-lib to the dependencies but would not follow the dependencies of that lib. So if some-lib had a dependency to some-other-lib that other lib would not be downloaded.
Maybe a bit more specific. Say, you need several libraries all using SLF4J as a logging interface. Maybe, some of the libraries require a slightly different version, but without any API differences. So they could all work with the same SLF4J version. You would then mark all theses libraryDependencies as intransitive and add SLF4J itself once as top level library dependency.
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % 1.7.6,
"com.typesage.slick" %% "slick" % "2.0.0" intransitive(),
"com.typesafe.akka" %% "akka-slf4j" % "2.2.0" intransitive()
)
Am I making sense?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With