Win a copy of Machine Learning with R: Expert techniques for predictive modeling this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

Conflicted dependencies? Should I be worried?

 
Greenhorn
Posts: 8
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

I'm using maven dependency "jersey-media-json-jackson" with version 2.23.2



I noticed from dependency graph that sub dependencies cause conflict with "jackson-annotations" as it is called up twice:

jersey-media-json-jackson -> jackson-annotations (v2.5.4)
jersey-media-json-jackson -> jackson-jaxrs-json-provider ->jackson-module-jaxb-annotations -> jackson-databind -> jackson-annotations (v2.5.4)

See IntelliJ graph attached



Maybe I'm bit OCD..... But do I need to worry about it or not?


jacksons.png
[Thumbnail for jacksons.png]
 
Rain Tüür
Greenhorn
Posts: 8
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For the life of me I can't find the edit button.

I mixed up version numbers and I meant:

jersey-media-json-jackson -> jackson-annotations (v2.5.4)
jersey-media-json-jackson -> jackson-jaxrs-json-provider ->jackson-module-jaxb-annotations -> jackson-databind -> jackson-annotations (v2.5.0)
 
Saloon Keeper
Posts: 10685
229
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In general, you want to avoid conflicting versions, because then it is up to Maven to decide which version to use, which is not always what you want. I think the best way to do this is not to reference dependencies in your project if they are already transitive dependencies through other dependencies. You want your dependency graph to be a tree as much as possible. However, when a dependency is included twice as a transitive dependency, you need to eliminate the version that you don't want to use:

This will exclude the version of the jackson-annotations library that jackson-databind uses, which is not a problem as long as the version that remains is backwards compatible with the version that you excluded.
 
Rain Tüür
Greenhorn
Posts: 8
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for answering

These conflicting transitive dependencies sure do look like a annoying problem. Especially if the one you would want to remove is the one further down the tree.


For example, this sure did fix the duplicate jackson-annotations problem but at same time  also induced even further problems.




I added screenshot of the graph.

Is it just a matter of learning maven the correct syntax to really get the graph to be to as much as tree as possible? How far would you personally go with it?
jacksons-databind.png
[Thumbnail for jacksons-databind.png]
 
Saloon Keeper
Posts: 21144
134
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rain Tüür wrote:Thank you for answering
These conflicting transitive dependencies sure do look like a annoying problem.



Conflicting transitive dependencies are Maven's equivalent to "DLL Hell". Very often when I upgrade a dependency in a complex POM, the dependencies cascade and not uncommonly conflict. The only cure is to start back-leveling dependencies until you find a mutally agreeable set. And hope that there is one!

This is another reason Maven POM files shouldn''t simply look for "the latest version" of dependencies, but call out specific versions by version-number. If you lock down version numbers, not only are you more or less guaranteed that anyone, anywhere, anytime can build an exact replica of your target, you also don't risk having a "working" POM break without warning. Which, thank Murphy, will happen when you least need the extra aggravation.
 
Rain Tüür
Greenhorn
Posts: 8
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:The only cure is to start back-leveling dependencies until you find a mutally agreeable set. And hope that there is one!



Cheers for te reply. What do you exactly mean with the statement above? What is the best methodology/approach to do this back-leveling of dependencies? Do you start to go down in the version numbers and hope there wont be conflicting transitive dependencies? Or do you use exclusions to try to get rid if conflicts?

Cheers
 
Tim Holloway
Saloon Keeper
Posts: 21144
134
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Both the Eclipse IDE Maven plug-in and the stand-alone Maven program have the ability to list transitive dependency chains. I've used both.

Basically, you're limited to the most advanced version of each dependency that's common to all parents, so you end up digging through parents to find versions that don't demand stuff that clashes. It's been a while since I had to do this, but I'm not sure there's an easier way to do this other than keep running backwards through parent version IDs until you get a good one.
 
Stephan van Hulst
Saloon Keeper
Posts: 10685
229
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rain Tüür wrote:For example, this sure did fix the duplicate jackson-annotations problem but at same time  also induced even further problems.


Your other problems are solved by excluding the two dependencies that you don't want, inside the dependency management for the dependency that requires them.

Keep doing this until your dependency graph is a tree.
 
Stephan van Hulst
Saloon Keeper
Posts: 10685
229
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wait, it doesn't make sense to me that suddenly 3 different versions of jackson-databind would be referenced. Can you show us your full POM?
 
Tim Holloway
Saloon Keeper
Posts: 21144
134
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Better yet, show us what you get from this:


You might want to review this page: https://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html
 
Sheriff
Posts: 21805
104
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:In general, you want to avoid conflicting versions, because then it is up to Maven to decide which version to use, which is not always what you want. I think the best way to do this is not to reference dependencies in your project if they are already transitive dependencies through other dependencies.


I've noticed that Maven will always use versions you declare as direct dependencies over whatever transitive dependency there is. That's why at work we directly declare Jackson as a dependency in Spring Boot applications just to bump the version (to get rid of some CVE warnings). The order in which you declare dependencies can also help, e.g. putting something like Hibernate Validator above JEE so that javax.validation comes from the former, not the latter (which causes issues like "no class body found"...).
 
Stephan van Hulst
Saloon Keeper
Posts: 10685
229
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Personally I'm not a big fan of that approach because it blurs the lines between direct dependencies and transitive dependencies. If my project doesn't directly depend on a certain library, I don't want to reference it directly. People tend to forget why a certain library is needed, and over time unneeded dependencies accumulate.
 
Rain Tüür
Greenhorn
Posts: 8
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks to everybody replying. I'm learning a lot.

The below are the dependencies of my pom. For the simplicity I do not have any exclusions in my project.




The below is the maven dependency:tree of my project.



If i run:


Then I get a result as:




If we are to believe the above then 2.5.0 is omitted. But this might not be the as according to this when using Maven 3 it might not be the case as it states:

the output from mvn dependency:tree can differ from the actual dependency tree used by Maven itself to derive the classpaths of a project



So this makes me curious of what does that red line on IntelliJ Maven Diagram represent? How can I truly understand what library is used?



I guess the only way to guarantee that the correct library will always be used is really to exclude the wrong ones from library.

So coming back to my problem.

If A has a dependency X..... X has a dependency Y.... Y has a dependency on Z (e.g. v2.5.0),
If B has a dependency on Z (e.g. v2.5.4)

Is there a way to exclude dependency Z (v2.5.0) when compiling A?
As far as I understand exclusions for a dependency only seem to go one level deep?



Thanks again for everybody's input.
 
Tim Holloway
Saloon Keeper
Posts: 21144
134
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Personally I'm not a big fan of that approach because it blurs the lines between direct dependencies and transitive dependencies. If my project doesn't directly depend on a certain library, I don't want to reference it directly. People tend to forget why a certain library is needed, and over time unneeded dependencies accumulate.



Who says we don't agree on anything?

To me, an indirect (transitive) dependency is something I don't want to explicitly declare because I want the direct dependencies to be as "black box" as possible (plus it keeps the POM simpler).

I don't need to declare explicit versions on indirect dependencies, since the direct dependencies already do that.
 
Stephan van Hulst
Saloon Keeper
Posts: 10685
229
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Tim Holloway
Saloon Keeper
Posts: 21144
134
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That red line is the indicator of your version conflict. jersey-media-json-jackson wants version 2.5.0 of jackson-annotations, but jackson-databind wants version 2.5.4.

If I'm reading correctly, the resulting build used version 2.5.4, and that's usually pretty safe, but there's no absolute guarantee, since some jars do not have full backwards compatibility. Backwards compatibility depends on the jar author and to a certain extent, chance as well, since there's always the potential for unknown interactions/bugs.

The ultimate reponsibility for the conflict is is jackson-jars-json-provider, but the more immediate offender is the jackson-databind jar. So what I'd do is see if I could override something in that chain to make it only demand the jackson-databind that requires version 2.5.0 of jackson-annotations. Depending on your good fortune, it may be as simple as explictly demanding an earlier jackson-databind in your POM all the way up to having to backlevel jersey-media-json-jackson.

Although if you have to backlevel the jersey jar, I'd wager that that particular jar was badly built, since its dependencies are all jackson dependencies. It's not like there's an odd log4j reference in there or something.

 
Stephan van Hulst
Saloon Keeper
Posts: 10685
229
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:Who says we don't agree on anything?


It was bound to happen at some point
 
Are you okay? You look a little big. Maybe this tiny ad will help:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!