Why does Maven include multiple versions of the same dependency?

I have a Maven java web app (.WAR) project that includes several libraries, including Wicket libraries (but I donโ€™t think that the problem itself is a gate, but rather with maven).

Here's the problem: even if I turn on only Wicket 6.20.0 , as a result .WAR contains two copies of the Wicket libraries: 6.20.0 and 6.18.0 , as you can see in this screenshot

enter image description here

Thinking of some conflicting imports, I printed a dependency tree using:

 mvn dependency:tree 

commnad ... but Wicket 6.18.0 is not mentioned in the dependency tree ! I also double-checked the use of Eclipse's "dependency hierarchy", and I cannot confirm the absence of this import.

I even searched for the line "6.18.0" in the entire workspace using Eclipse, but it was not found anywhere!

How can I find out what causes the inclusion of this repeating version of the library?

+5
source share
5 answers

Maven does not work this way.
Resolving more than one dependency with the same artifactId and groupId, but with a different version, will result in one dependency (the version used is not deterministic).

The presence of two artifacts with the same artifactId and groupId, but with two different versions in the same lib WAR folder, is probably due to one of them:

  • you are not running mvn clean package , but only mvn package .

  • uses a corrupted version of the Maven war plugin. Try updating it to check it out.

  • you have a Maven plugin that copies Wicket jars 6.18.0 to the WEB-INF/lib folder of the target folder during component build.

  • The maven WAR project you are building has a WAR artifact as a dependency. In this case, WAR dependency dependencies overlap in the WAR project you are building.


An interesting Maven issue about duplicate JARs due to WAR dependencies:

JARs with different versions may be in WEB-INF / lib with war as dependencies


Your answer and your comment show that you actually have a WAR dependency in your assembly.
Unfortunately, in fact, there is no effective and long-term effective solution to circumvent this limitation.

As my comment says, using the packagingExcludes property of the maven war plugin is a valid workaround for the actual problem:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <!-- ... --> <packagingExcludes>WEB-INF/lib/wicket-*-6.18.0.jar</packagingExcludes> </configuration> </plugin> 

But be careful, using this will make your build less reliable over time. The day you update the WAR dependency version, and that in the new version it pulls out another version of the gate again, you still run the risk of having duplicated jars with two different versions in your built-in WAR.

Using the overlay function , specifying the overlay maven-war-plugin element is generally better, as it focuses on the overlay used for military dependence. He fixes the problem earlier. As a result, you can define to exclude any calibration JARs from the WAR dependency:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <version>2.4</version> <artifactId>maven-war-plugin</artifactId> <configuration> <overlays> <overlay> <groupId>com.whatever.youlike</groupId> <artifactId>myArtifact</artifactId> <excludes> <exclude>WEB-INF/lib/wicket-*.jar</exclude> </excludes> </overlay> </overlays> </configuration> </plugin> 

This method is better, but it is still a workaround.
On the day that WAR WAR is updated, and that it pulls out new dependencies (other than Wicket) that were declared in your real build, but with different versions, you can complete the same problem.

I think that declaring WAR artifact dependency should only be done because we have no choice.
Since it is possible to refactor priests and projects, introducing a common JAR dependency, on which two WARs depend, and which contains only common sources and resources for two WARs, makes things simpler.

+5
source

Well, I realized this when I poked.

I had a war type dependency in the project:

 <dependency> <groupId>com.whatever.youlike</groupId> <artifactId>myArtifact</artifactId> <version>1.0.7-SNAPSHOT</version> <type>war</type> </dependency> 

Apparently (I didn't know about it, my mistake is here), these types of dependencies will include themselves in the class path by copying all the libraries to the main WAR / libs folder, but this will NOT show the application in the dependency / dependency hierarchy tree.

I decided by setting an explicit exception in the WAR plugin:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <!-- ... --> <packagingExcludes>WEB-INF/lib/wicket-*-6.18.0.jar</packagingExcludes> </configuration> </plugin> 
+2
source

Use clean install and the double dependency is likely to disappear.

+1
source

Because other libs may use the same libraries, but a different version, or you tried a different version and did not mvn clean

0
source

The mvn dependency:tree command tells you the correct information - what you are looking at here is an eclipse / build problem.

Clean all target and assembly objects in your project. If necessary, check it from the source control to a new folder.

Alternatively, you can create your project in IntelliJ IDEA and see if you have the right dependencies (most likely you will).

0
source

Source: https://habr.com/ru/post/1268985/


All Articles