I have below structure for the project.
project
|_build.properties
|_plugins.sbt
Core
Module1
Module2
build.sbt
In Module1 and Module2, I use the same dependency in different versions. Then I aggregate the 2 modules with Core module. Then one dependency is getting evicted by another version. How do I keep both dependency versions?
Update: The expected dependency tree is as follows:
core_1.0-SNAPSHOT
-module1_1.0
--org.milyn:milyn-smooks-core:1.1
-module2_1.0
--org.milyn:milyn-smooks-core:1.5.2
module1_1.0-SNAPSHOT
-org.milyn:milyn-smooks-core:1.1
module2_1.0-SNAPSHOT
-org.milyn:milyn-smooks-core:1.5.2
And, what I getting is as follows:
core_1.0-SNAPSHOT
-module1_1.0
--org.milyn:milyn-smooks-core:1.1 (evicted by 1.5.2)
-module2_1.0
--org.milyn:milyn-smooks-core:1.5.2
module1_1.0-SNAPSHOT
-org.milyn:milyn-smooks-core:1.1
module2_1.0-SNAPSHOT
-org.milyn:milyn-smooks-core:1.5.2
How can I disregard the eviction?
In 99% of cases you don't want to have two versions of the same dependency. Assuming they contain same classes (as in the same name), it will cause runtime errors as only one version will be loaded (first come, first loaded).
What you likely want to do is:
either let the eviction do its work (it should pick up most recent version)
or, define the same version across all your modules
or, define some dependencyOverrides in your "Core" module to force a version (which can be the one of "Module1", "Module2", or even another one)
Related
I created a NuGet package with an empty logger and my package depends on Microsoft.Extensions.Logging.Abstractions.
My PackageReference line and my dependency in the .nuspec file are set to 1.0.0 with no special syntax which I understand means >=.
My empty logger works just fine with this version and I thought using the lowest working version of the abstractions lib would make my package easier to consume by applications which are likely to have greater versions.
However, when I've referenced my package from an xUnit test project I have a red compiler error CS1705.
My test project references two packages:
The project its testing, which is an ASP.NET Core Razor Pages site that in turn references the same logging abstractions package which is included in Microsoft.AspNetCore.App 2.2.0 metapackage.
My empty logger package, which, in turn references the logging abstractions 1.0.0.0 as I have described.
Compiler error from the test proj says:
Assembly (Razor Pages proj) uses (Abstractions 2.2.0.0) which has a higher version than referenced assembly (Abstractions) with identity (Abstractions 1.0.0.0).
My package can use the higher version so what am I missing?
Edit
Here's a high fidelity diagram ;)
T is "xUnit Proj".
W is the "Website Proj" under test.
E is the empty logger package (Evoq.Instrumentation on nuget.org)
A is metapackage Microsoft.AspNetCore.App 2.2.0
L is Microsoft.Extensions.Logging.Abstractions
There's the nearest wins rule, which I think means that the dependency from T to L via E would win and version 2.0.0 would be used but I'd expect a package downgrade warning not a hard compiler error.
Nearest wins: https://learn.microsoft.com/en-us/nuget/consume-packages/dependency-resolution#nearest-wins
Edit 2
It just occured to me that T > W is a project reference. So maybe that's short-circuiting the NuGet resolution. I'll add a ref from T to A directly and see if that solves it.
I forgot T > W is a project reference. So I think that was short-circuiting the NuGet resolution I was expecting to take place.
I added a ref from T to A directly and that solved it.
I want to understand the dependencies for a multi-module maven project and for that referred to eclipse dependency hierarchy.
I did understand fairly, however some of the things I am not able to understand at all.
Below is the screen shot.
The things which I didn't understand are:
--> managed from 1.0.2 [Compile}
--> managed from 1.0.2 (omitted for conflict with 1.0.0) [Compile]
I did search online but I got information in traces. Can anyone help me understand what they mean in easy to understand?
Thanks.
Maven builds a flat classpath from the dependency tree each for compiling ([compile]), for testing, and for running.
In a flat classpath, unlike OSGi, a dependency can only exist in one version. In your cropped screenshot, there is on the second level among other things:
kafka-streams 1.0.2 and
kafka-clients 1.0.0.
kafka-streams 1.0.2 requires kafka-clients 1.0.2 which conflicts to kafka-clients 1.0.0. Therefore kafka-streams 1.0.2 is omitted for conflicts with 1.0.0 even if the version 1.0.2 is required here ("managed from 1.0.2").
More detailed:The classpath which is used to compile or run a plain Java application is flat: all required libraries are globally specified as an ordered list. It is not possible to use a library of a specific version for one package and for another package the same library in a different version.In Maven dependencies builds a tree: each dependency might have its own dependencies. Maven maps the tree of dependencies to the classpath, an ordered list of libraries. If in the Maven dependencies tree the same library exists in different versions, it is not possible to create a flat classpath. This is a conflict.This conflict is resolved by picking one version and omitting all other versions. At the place where the picked version is used instead of the required version, (managed from <required but not picked version>) and (omitted for conflict with <picked version to use instead>) is displayed.In addition, Maven can create different classpaths to compile, to test or to run a Java application via so-called scopes. The [compile] scope is the default scope for using a library in all tasks: compiling, testing and running.
Make sure that the versions specified in the pom.xml file are compatible with each other (which is not yet the case in your screenshot): you have to upgrade kafka-clients from 1.0.0 to 1.0.2 (or downgrade the other libraries).
I am working on a multi-module maven project, which have the module with different versions of the scala, the reason being the new module say B was added which required the higher scala version i.e 2.11 and rest of the project is build around scala 2.10.
Now I have a use case where I need to call a method from the class of B to the one with lower version.
which results in the dependency conflict.
Is there any way for which I can define the version of dependencies i.e to use lower version to compile.
I have a project with several utility classes. Let's name it Utils.
I have a proj1 which depends on Utils. And another proj2 that depends on proj1 and Utils.
The problem is if both proj1 and proj2 depend on different Utils version this will lead to problems.
What's the best solution?
This situation occurs in Scala/SBT projects, but I guess other languages have the same problems.
Edit:
Just to be clear, proj2 is the project that will run, that uses some code from proj1 and Utils.
This is classic Jar Hell, and it is a problem on any JVM based project not just scala with sbt.
There are 4 common solutions
Get rid of conflict by changing code, consolidate your multiple version dependency into a single dependency.
Shading (as mentioned above by #Sean Viera)
Multiple ClassLoader component architecture like OSGI (as mentioned by #tuxdna)
Run in separate JVMs like a microservice architecture (also mentioned by #tuxdna)
You have three different projects:
Utils
proj1 <- depends on Utils v1
proj2 <- depends on Utils v2
The only way you can be 100% sure that there are no conflicts between proj1 and proj2 is to run them in isolation.
As soon as you will mix proj1 and proj2 with different versions of Utils on the same classpath, you will end up override one or the other project.
You can achive isolation using:
run them in separate JVMs, with appropriate version of Utils
run them in same JVM but in different class loaders
I've just downloaded Play Framework 2.1-RC1.
Within folders, I noticed that SBT folder includes itself Scala's compiler/library whose version is:
scala.2.10.0-RC1.
Previously, I used to compile some Scala programs with the more recent version:
scala.2.10.0-RC2
Should I stay with scala.2.10.0-RC1 provided by Play (in order to avoid potential incompatibility with Play)?
Further, is there a way (a specific Play's command-line?) to add automatically src-jars for Scala into Play's SBT folder (scala-library-src.jar etc...)? Indeed the folder structure contains currently only jars files:
jansi.jar
jline.jar
scala-compiler.jar
scala-library.jar
scala-reflect.jar
Scala 2.10.0 final has been out for about a week, now. I'd expect that the Play artifacts are available for it by now and if they're not they surely will be soon.