how to manage same jar of different versions in maven dependencies? - spring

need to add the Dependencies of spring web jar 3.1.3 and 3.2.2 in the same pom.xml.
Does maven support the same jar of different versions?

In addition to this,
Maven does that in a different way. If there are two dependency declarations with different versions, the higher version takes the precedence.
EDIT1 :
This statement is for the direct dependency declaration in the same pom. Forcing the required version to use is the strategy here.
Maven uses dependency mediation to resolve the version conflicts.
AFAIK, as the higher versions always have backward compatibility, preferred is to use the higher version.
Unless there is a very strong reason behind adding a specific version, it all goes to designing the modules and their hierarchy.
This gives you complete insight of how to manage the dependencies using modules.
This describes the conflict resolution scenarios.
EDIT2:
For the transitive dependencies, yes the nearest definition is the strategy followed. As in example.

Related

Force Maven to use latest dependency among the ones present in dependency tree

I understand Maven's behavior whenever it finds more than one version of the same dependency is to choose the one closer to the dependency root. If more than one are same as close, then it will choose the first one it finds.
Is there a way to change this behavior and make it simply pick the highest version?
The versions plugin can do some of the work for you, by rewriting your POM, but I highly recommend avoiding using it. Explicitly managing dependencies as gogstad and Michael stated is the recommended path.
Add a dependency management section and pick the version you actually want to use. You should always be setting versions so you're getting repeatable builds.
No, it's not possible to change the maven dependency mechanism to anything other than nearest definition.
If you experience that maven chooses the wrong dependency, the only way to fix it is to explicitly depend on that dependency in your application (maven will of course not allow two different versions of the same dependency in the clasdpath at the same time). The dependency you define will be used in any transitive dependencies for the same artifact.

How two know when a maven project has the same transitive dependenciy twice of different versions?

I have to add a new dependency to a maven project. This dependency has four transitive dependencies(according to http://mvnrepository.com/) and between them, there is spring-data-jpa jar.
The maven project I am working in has many dependencies configured in the pom so I understand there could be a big possibility that there is already a spring-data-jpa dependency in the project(transitive or not).
When you work in a large project with many dependencies and you have to add a new one, how to check if there is already the same transitive dependency of a different version? I have to check manually the transitive dependencies for each direct dependency configured? Has maven a warning for this situation?
How maven works in this situation? I mean, there could be two spring-data-jpa jars of different versions(this would be a problem) or maven resolves this in another way?
The simple answer is that the dependency plugin can tell you. The longer answer is that there are a number of different situations to consider about transitive dependency management, and how the plugin helps and what to do about it differs for each one.
Maven automatically chooses which dependency to include if two dependencies have the same coordinates (groupId, artifactId) with different versions. Broadly speaking, it picks the version that's highest in the tree - effectively overriding dependencies defined in downstream transitive dependency poms. So, if you have two different versions of exactly the same dependency then you will still only find one version of the dependency on the relevant classpath.
The dependency plugin can help you identify this situation by highlighting points where its made a decision, but you probably want to use the dependencyManagement section of your top-level pom to ensure that the dependencies which you bring in are the ones you expect.
Separate difficulties can arise when a dependency changes its groupId or artifactId. Then you can get two dependencies on the classpath - one with an old version on the old coordinates and one with the new version on the new coordinates. As examples, Spring, Hibernate and Apache commons have all found themselves doing this at some point or another. In this case all you can do is use to the dependency plugin to identify duplicated dependencies and then use exclusions tags to explicitly exclude them as transitive dependencies from the dependencies which are pull them in.
It's important to note that all of this dependency management can cause unintended breakage. If the thing that your application depends on really does depend on some specific version of a package as a transitive dependency then you can break it by overriding that version. So testing the features that you use is essential.
Have you tried the Maven Dependency Plugin? There's some useful goals you can run, such as mvn dependency:tree etc.

Maven direct and transitive dependencies resolution

Artifact_A has both the direct dependency and the transitive dependency on Artifact_B within the same scope.
Does the direct dependency always precede the transitive dependency, or the one of higher version prevail?
Is there any reference with better illustration on Maven Dependencies Resolution than the chapter Maven reference manual - Project Dependencies?
The dependency-resolution mechanism can be complicated. If there's a managed version (dependencyManagement), then that will take precedence. Generally speaking, Maven will use the highest-requested version that satisfies all of the requirements (for example, some servlet package might require [2.4,3.0) while another package requires 2.5, so Maven will use 2.5). If Maven can't find such a version (in the above sample, if the second package required [3.0,4.0)), then it will produce an error.
If you have a specific issue that you're running into, feel free to post a question with all the details.

Maven with OSGI dependencies

I'm using maven copy-dependencies to copy my OSGI bundle dependencies to some location. Somewhere in my dependency graph I have two versions of the same artifact and maven's resolution ignores one. Anyway I can avoid this and force maven to resolve multiple versions of the same artifact?
One of mavens core feature is Dependency mediation. If you have two versions of the same artifact on you graph maven will try to find the nearest version (it does not "ignore one" but decides to use the other one):
Quote:
"Dependency mediation - this determines what version of a dependency
will be used when multiple versions of an artifact are encountered.
Currently, Maven 2.0 only supports using the "nearest definition"
which means that it will use the version of the closest dependency to
your project in the tree of dependencies."
In opposite of OSGi where you can have the same bundle in different versions maven will always resolve the dependencies in a way that an artifact only exists in one (the nearest) version. If this is not possible (e.g. because to different versions are forced) you will get a conflict and the build will fail.
You can use Embed-Dependency tags in maven-bundle-plugin, however that may not be the best approach.
I've created this blog which explains in great detail how to cope with this OSGi issue in several ways, you might want to chose the one which fits you best: http://www.citizenrandom.com/?cat=2

Maven dependency conflict:snapshots has no priority

When there is a conflict in the dependency tree (same artifact but different versions) then, AFAIK, Maven will resolve the conflict by selecting the highest version of the dependency and will omit the 'old' ones.
However, when the newer version is a SNAPSHOT then apparently it will choose the older stable version over the SNAPSHOT.
In my case: some-artifact: 0.5.0-SNAPSHOTS (omitted for conflict with 0.4.0) => version 0.4.0 is picked over the wanted 0.5.0-SNAPSHOT.
I assume this functions as designed but I don't understand the reason why. Next to that, any idea if there is a way to tell Maven to take the SNAPSHOT over the stable version?
Your assumption about Maven's always selecting the highest version isn't accurate. Artifacts are chosen based on a number of factors including depth of the dependency in the tree, order in the tree, whether the dependency is a snapshot or a release, and dependency management, which pretty much overrides everything else.
Unfortunately, I don't know of any one, definitive source of information on Maven's dependency resolution algorithms. You'll find bits and pieces of it scattered all over. A few handy references:
Introduction to the Dependency Mechanism gives an overview of the topic with a good, if short, section on Transitive Dependencies and how they're selected from a dependency tree.
The Sonatype Maven book has a more thorough section on Project Dependencies in general that will add a lot to your knowledge about the subject.
An earlier section of that same book discusses Project Versions, which is strongly related to this problem and has a good section on SNAPSHOT versions, though not as much as I could wish on how they play into dependency resolution.
Project Relationships talks about the coordinate system and how project inheritance affects what dependencies get included.
Finally, the POM Reference is a good jumping-off point for almost anything to do with the pom. There's at least a brief description of every pom element that can help you understand enough to be able to begin searching for more info effectively.
As for some practical advice, the output of mvn dependency:tree is highly useful in discovering why a particular version of a dependency was chosen. It'll often even tell you something like "foo:bar:1.2 (was 1.1)". Once you figure out where the errant version is coming from, there are a number of ways to ensure a specific dependency version is used for a project:
Exclude wrongly-versioned dependencies from other dependencies that are causing them to be included in the build.
Add an explicit top-level dependency to your pom instead of relying on a transitive dependency.
List the dependency in the dependencyManagement section of your pom (scroll down a bit from this link) to force the dependency to have the specified characteristics, regardless of what level of transitive dependency it is. Use this option with care, as dependencyManagement is viral, in that other projects depending on your project will be "infected" with your dependency management. There's also a good section on dependency management in the pom reference.
If the 0.4.0 version is being pulled in as a transitive dependency via another dependency in your POM, then you should be able to exclude it. The dependency:tree goal should help you see if this is what's happening.
Maven is designed to favor release versions over snapshot versions. I'm not sure why you would have two dependencies in the same POM and not be able to resolve a conflict by removing one, so I will assume that one of the dependencies is inherited from a parent pom. In this case you can set the inherited dependency as <optional>true</optional> and I THINK it should allow the child POMs to override it, even with a lower version.
bad/hacky solution for if that doesn't work - edit your local repository in such a way that it doesn't realize the 0.5.0 version is a snapshot (or even edit your private nexus repo if you have the ability)

Resources