I am using Maven 3 to build a java application with 3 tiers - server, ejb and ui. The EJB project is dependent on the Server project, and the UI project is only dependent on EJB, and provides an exclusion for the Server transitive dependency.
When the UI project is built as a war, the Server dependency is being included despite it not showing up on dependency:tree command.
Here is the relevant output of running mvn dependency:tree
**project.name:UI:war:1.0 SNAPSHOT**
+- project.name:Common:jar:1.0 SNAPSHOT:compile
| + org_common:_lib:jar:16.0.006:compile
| | +- log4j:log4j:jar:1.2.16:compile
| | \- commons configuration:commons configuration:jar:1.6:compile
| | +- commons lang:commons lang:jar:2.4:compile
| | +- commons digester:commons digester:jar:1.8:compile
| | \- commons beanutils:commons beanutils core:jar:1.8.0:compile
| +- org_common:_security_lib:jar:16.0.006:compile
| \- org.springframework:spring:jar:2.0:compile
+- **project.name:EJB:ejb client:client:1.0 SNAPSHOT:compile**
| \- com.ibm.websphere.appserver:j2ee:jar:7.0.0.9:compile
+- org_common:_uicomponent:jar:16.0.006:compile
And here is the output dependency tree from when running mvn clean install -X
**project.name:UI:war:1.0 SNAPSHOT**
+- project.name:Common:jar:1.0 SNAPSHOT:compile
| + org_common:_lib:jar:16.0.006:compile
| | +- log4j:log4j:jar:1.2.16:compile
| | \- commons configuration:commons configuration:jar:1.6:compile
| | +- commons lang:commons lang:jar:2.4:compile
| | +- commons digester:commons digester:jar:1.8:compile
| | \- commons beanutils:commons beanutils core:jar:1.8.0:compile
| +- org_common:_security_lib:jar:16.0.006:compile
| \- org.springframework:spring:jar:2.0:compile
+- **project.name:EJB:ejb client:client:1.0 SNAPSHOT:compile**
| +- **project.name:Server:jar:1.0 SNAPSHOT:compile**
| | +- javassist:javassist:jar:3.4.GA:compile
| | +- project.filestore:filestore_client:jar:7.0.003:compile
| | +- com.ibm.db2:db2jcc:jar:9.7.fp1.aix64.s091114:compile
| | +- com.ibm.db2:db2java:jar:9.7.fp1.aix64.s091114:compile
| | +- com.ibm.db2:db2jcc_license_cu:jar:9.7.fp1.aix64.s091114:compile
| \- com.ibm.websphere.appserver:j2ee:jar:7.0.0.9:compile
+- org_common:_uicomponent:jar:16.0.006:compile
The dependency on Server is the only difference between the two trees. Shouldn't these two outputs always be the same? What could cause a library to be included that does not show up in dependency:tree?
The parent POM defines the modules as:
<modules>
<module>Server</module>
<module>EJB</module>
<module>UI</module>
</modules>
The dependency listed in the EJB POM is:
<dependencies>
<dependency>
<groupId>project.name</groupId>
<artifactId>Server</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
The dependency in the UI is:
<dependencies>
<dependency>
<groupId>project.name</groupId>
<artifactId>EJB</artifactId>
<version>${project.version}</version>
<type>ejb-client</type>
<exclusions>
<exclusion>
<groupId>project.name</groupId>
<artifactId>Server</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
I am aware that I can explicitly exclude the Server jar from being included in the WAR, but I would prefer to fix the actual issue.
A project's dependency tree can be filtered to locate specific dependencies. For example, to find out why Velocity is being used by the Maven Dependency Plugin, we can execute the following in the project's directory: mvn dependency:tree -Dincludes=velocity:velocity.
By taking advantage of Maven's nearest definition logic, developers can override the version of a dependency by declaring it on the root pom. xml file.
Maven has six default dependency scopes. And it's important to understand that each scope — except for import — has an impact on transitive dependencies.
There are three built-in build lifecycles: default, clean and site. The default lifecycle handles your project deployment, the clean lifecycle handles project cleaning, while the site lifecycle handles the creation of your project's web site.
You are right that the output should be same in both the cases. However Maven 3 moved to using Aether for dependency resolution but as of now dependency:tree uses the old mechanism of dependency resolution which is why the difference. Check out the following link for details.
https://cwiki.apache.org/MAVEN/maven-3x-compatibility-notes.html#Maven3.xCompatibilityNotes-DependencyResolution
Because of this reason you should only rely on the output of mvn clean install -X for dependency management.
Edit
Since version 2.5 of the Maven Dependency Plugin, dependency:tree
also uses Aether (see the bug report, and the release notes)
As we figured out in comments, the problem's source was buggy Maven 3.0.3. Version 3.0.4 has solved the issue.
My comment there:
Which exact Maven version do you use? If not 3.0.4, try it and tell if it helps. I've found really, REALLY crappy issues while using previous Maven 3 releases, mostly with 3.0.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With