Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven Build different to Dependency Tree

Tags:

java

maven

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.

like image 357
J Barclay Avatar asked Apr 05 '12 03:04

J Barclay


People also ask

What is Maven dependency tree?

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.

Does Maven override dependency version?

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.

Does Maven support different dependency scopes?

Maven has six default dependency scopes. And it's important to understand that each scope — except for import — has an impact on transitive dependencies.

What are the three builds in the Maven life cycle?

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.


2 Answers

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)

like image 179
Swapnil Avatar answered Sep 29 '22 16:09

Swapnil


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.

like image 22
Michał Kalinowski Avatar answered Sep 29 '22 15:09

Michał Kalinowski