To me, maven has been great for managing dependencies between jar files. But
there is still one thing that bugs me -- regarding unnecessary dependencies,
For example, we may have pom.xml that says Artifact A depends on B, and B depends on C. But there are extra information (via email, forum, etc) that tells us that A does not really use C. An example of that would be this
[INFO] +- org.apache.hive:hive-exec:jar:2.3.0:compile
[INFO] | +- ...
[INFO] | +- org.apache.calcite:calcite-core:jar:1.10.0:compile
[INFO] | | +- ...
[INFO] | | \- org.pentaho:pentaho-aggdesigner-algorithm:jar:5.1.5-jhyde:compile
The author of C (in this example org.pentaho:pentaho-aggdesigner-algorithm) would
tell me (via an Internet forum) that (link):
Note that when Hive uses Calcite it doesn't use
pentaho-aggdesigner-algorithm (either at compile time or at run time),
so you can safely exclude that dependency.
I know how to exclude the dependency, and my question here is whether there
a more intelligent way to determine that a dependency is not really
needed? Or we really rely on the pom.xml to be very accurate in terms of
their dependencies?
My another example is this: I see this dependency:
[INFO] +- org.apache.hadoop:hadoop-common:jar:2.7.3:compile
[INFO] | +- org.apache.hadoop:hadoop-annotations:jar:2.7.3:compile
[INFO] | | \- jdk.tools:jdk.tools:jar:1.8:system
I suspect that the dependency on jdk.tools is not
really needed. But how do I know for sure? Is there
a better way than trial and error or contacting the developers?
Related
I need to create a jar-with-dependencies. I'm using maven assemply plugin 3.1.0.
I want to:
include dependencies with scope compile and that, transitively
exclude dependencies with scope provided.
IE, in the following case as shown by mvn dependency:tree:
[INFO] +- com.jayway.jsonpath:json-path:jar:2.2.0:compile
[INFO] | +- net.minidev:json-smart:jar:2.2.1:compile
[INFO] | | \- net.minidev:accessors-smart:jar:1.1:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.16:provided
I want to include in the final jar json-path, json-smart, accessors-smart but NOT slf4j-api.
With the default jar-with-dependencies descriptor, I also have slf4j-api included in the resulting jar.
1/ Is it the intended behavior? This seem in contradiction with other maven resolution.
2/ what is assembly descriptor that allows to get what I want?
Thanks
So, it seems to just not work with the assembly plugin, and until explained why it is otherwise, I believe it's a bug: https://issues.apache.org/jira/browse/MASSEMBLY-883
I created a minimal project to demonstrate the problem here: https://github.com/fanf/test-maven-assembly
The solution is to use the shade plugin (https://maven.apache.org/plugins/maven-shade-plugin) which is correctly excluding transitive dependencies with scope provided (and can do many more things than the assembly plugin regarding uber-jar).
I am learning Spring and Hibernate with Maven. However I am not able to understand the incompatible package issue. There is not such information about which Spring package is compatible with which Hibernate packages. It's like I have to copy the POM file from existing working projects. But I am not convince with this approach. There must be some way to know the compatibility between the dependencies.
Also there is no way to determine which packages are to be included if I wanted to work with Spring and Hibernate.
I am sure there must be a way. Please help me.
I understand you question in that way, that you want to know wich versions to use (not which dependencies to use at all)
You could have a look at the spring boot poms. (I do not want you to use Spring Boot).
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
(https://github.com/spring-projects/spring-boot/blob/master/spring-boot-dependencies/pom.xml)
They contain a lot of knoweleg which versions work together well.
For example:
<spring.version>4.2.4.RELEASE</spring.version>
<hibernate.version>4.3.11.Final</hibernate.version>
Maven has a plugin that shows dependencies of an artifact in a tree view. You can use it to see dependencies of a pom.xml. For example, you can download pom.xml from jCenter or Maven Central, and run the following command:
mvn -f your-downloaded-pom.xml dependency:tree
And it will show something like that:
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # spring-orm ---
[INFO] org.springframework:spring-orm:jar:4.1.6.RELEASE
[INFO] +- aopalliance:aopalliance:jar:1.0:compile
[INFO] +- javax.jdo:jdo-api:jar:3.0.1:compile
[INFO] | \- javax.transaction:jta:jar:1.1:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:compile
[INFO] +- org.apache.openjpa:openjpa:jar:2.2.2:compile
....
If you want to know the hibernate dependencies for Spring, you can obtain Spring-ORM pom.xml for the version you want, for example 4.1.6.RELEASE and run the following command:
mvn -f spring-orm-4.1.6.RELEASE.pom dependency:tree | grep hibernate
and you will get this:
[INFO] +- org.hibernate:hibernate-core:jar:4.3.8.Final:compile
[INFO] | +- org.hibernate.common:hibernate-commons-annotations:jar:4.0.5.Final:compile
[INFO] | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.6.10.Final:compile
So this is how you can get it.
Hope it helps!
I have 2 projects, when I list the dependencies of the first I get:
[INFO] com.onespatial.gothic:gothic-java:jar:5.16
[INFO] +- com.onespatial.tools.gde:gde-cfg:zip:5.16:provided
[INFO] +- com.onespatial.gothic:gothic-w32:jar:5.16:compile
[INFO] \- com.onespatial.gothic:gothic-lx86_64:jar:5.16:compile
which is correct. The gde-cfg is provided. However when I list the dependencies of the second project, which includes the above project, I get:
[INFO] +- com.onespatial.radius.studio:rswebmapservice:jar:classes:2.3.4-build-7-SNAPSHOT:compile
[INFO] | +- com.onespatial.gothic:gothic-java:jar:5.16:compile
[INFO] | +- com.onespatial.gothic:gothic-lx86_64:jar:5.16:compile
[INFO] | +- com.onespatial.gothic:gothic-w32:jar:5.16:compile
The transitive dependency of gothic-java is not appearing in the tree (or when I use dependency:list). Can anyone explain why gde-cfg is not being listed above.
As described in the Maven docs, transitive provided dependencies are not added to the dependency tree. There is a bug report from 2006, with no progress since.
You are meant to declare all the dependencies you are using in your project, in the sense that if you are using classes from gde-cfg, you should declare it in your dependencies, unrelated to whether there is a transitive dependency on it.
The only case that I can think of where the dependency would be necessary without you not actually using any classes from gde-cfg, is if you are extending a class/interface from gothic-java, and this class/interface extends a class/interface from gde-cfg. In this case the class/interface would have to be present at compile time, which it is not in Maven’s current behaviour. The workaround would be to manually add a provided dependency to gde-cfg to your project.
Should "mvn dependency:list -DincludeScope=compile" include child dependencies of test scope deps?
My project depends on "org.apache.httpcomponents:httpclient:jar:4.1:test"
and httpclient depends on "org.apache.httpcomponents:httpcore:jar:4.1:compile"
If I look at compile scope dependencies, I do not expect to see anything below httpclient since it is test scope and that branch of dependencies should be filtered out.
However, the following includes core" lists httpcore
mvn dependency:list -DincludeScope=compile -DexcludeScope=test|grep -i http.*core
[INFO] org.apache.httpcomponents:httpcore:jar:4.1:compile
My Project's dependency:tree output
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.1:test
[INFO] | +- org.apache.httpcomponents:httpcore:jar:4.1:compile
[INFO] | +- commons-logging:commons-logging:jar:1.1:test
[INFO] | \- commons-codec:commons-codec:jar:1.4:compile
Am I missing a flag that handles this "properly" or am I misunderstanding what proper is in this situation.
Oh, it's a bug (http://jira.codehaus.org/browse/MNG-3089) explained in this thread http://www.mail-archive.com/dev#maven.apache.org/msg68011.html but not fixed.
I'm working on a unit test in code that I haven't looked at before. I noticed that I was getting a NoSuchMethodError with a SLF call. This apparently is due to different versions of the SLF pieces in the dependency tree. I see both 1.6.1 and 1.5.2 in various places. I traced it back to one peer pom that was either referencing version 1.5.2 or none (the 1.5.2 reference was in a plugin dependecy, and the "none" was in the main dependency list). I changed both references to 1.6.1. I ran "mvn install" for that module. I looked at the generated POM in my ~/.m2/repository tree, and it showed both as 1.6.1. I then ran a "mvn dependency:tree", which the following excerpt is from:
[INFO] +- com.somepath.bundle:com.somepath.jira-connector:jar:1.0.0-SNAPSHOT:compile
[INFO] | +- org.apache.axis:axis:jar:1.4:compile
[INFO] | +- org.apache.axis:axis-jaxrpc:jar:1.4:compile
[INFO] | +- org.apache.axis:axis-saaj:jar:1.4:compile
[INFO] | +- commons-discovery:commons-discovery:jar:0.4:compile
[INFO] | +- wsdl4j:wsdl4j:jar:1.6.2:compile
[INFO] | +- org.slf4j:slf4j-simple:jar:1.5.2:compile
It's still thinking it's referencing 1.5.2, even after I changed both references in the "jira-connector" pom to 1.6.1.
When I run "mvn test" from the command line, the results are consistent with this, as SLF complains that it found multiple bindings, one of which is the 1.5.2 version.
Use dependency exclusion mechanism to specifically exclude the 1.5.2 version that is coming from jira-connector.
I've managed to get through this. I added specific references to both sl4fj-simple and slf4j-api for version 1.6.1 into both projects in question, and now it's ok with it. This should be defined in a common place, but this will work for these purposes.