0

This is as much a question about the use of maven <dependencymanagement> section as much as it is about how and EAR module should play out.

I have a typical use case. Following are the maven modules

  • parent
    • api
    • ejb
    • web
    • ear

ear has api, ejb and web listed as its dependencies and inherits from parent like the other modules.

Here is the dependency management section for parent.

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.4</version> </dependency> </dependencyManagement>

and for ejb I have a dependency (not under dependency management section but a dependency) with an explicit override of the version.

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>2.5</version> </dependency>

When I build the whole project from the parent (since they are aggregated in the parent pom), the EAR project creates the end EAR artificat.

So far so good, but the problem arises in the way the dependencies resolve. My instinct would be that because the ejb module lists spring core version 2.5 explicitly, that would get packaged as the dependency. But what actually happens is that the EAR module being a child of the parent pom uses the version mentioned in the dependency management section of the parent and ends up taking 3.4 as the spring core version.

After a lot of study I was convinced that this is as per the Maven documentation. But what I now think about is if I combine the strategy of having the parent pom controlling all dependency versions with the strategy of the EAR module inheriting the parent, I am essentially 'stuck' with (in some cases) what the parent defines with no chance to override it.

Although one could argue that one should ideally have the same version of the jar throughout, there are some situations you run into where you would like to override some dependency versions.

What is the correct approach to let me be able to override a version? The use of spring in this example is just for example purposes. It could be any other jar.

Devu
  • 381
  • 3
  • 15

1 Answers1

0

Dependency Management actually allow you to centralize the management of dependency versions without having to add dependencies within all children (talking about common dependencies). This brings much help when having multi-inheritance level project where children get the could get the transitive dependencies from the parent pom just like your project.

Concerning version override, don't be mistaken because you can override the inherited dependency version just by declaring it in the sub-module who needs to have its own version of some artifact.

Here is a sample showcase of that, stating a straightforward project with name root and having two sub-modules; blessed-module the one that inherite his parent artifact version and an odd-module which has chosen his own path and so his own artifact version:

root
\+ blessed-module 
 + odd-module

The parent pom will state the centralized dependencies having below descriptor (pom.xml):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>dependency.management.showcase</groupId>
  <artifactId>root</artifactId>
  <packaging>pom</packaging>
  <version>1.0</version>

  <modules>
    <module>blessed-module</module>
    <module>odd-module</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>3.2.8.RELEASE</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

</project>

The child modules will be as follows, starting with the good blessed-module:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>dependency.management.showcase</groupId>
    <artifactId>root</artifactId>
    <version>1.0</version>
  </parent>

  <artifactId>child-module</artifactId>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
    </dependency>
  </dependencies>

</project>

and the pom.xml file of the odd-module:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <artifactId>root</artifactId>
    <groupId>dependency.management.showcase</groupId>
    <version>1.0</version>
  </parent>

  <artifactId>odd-module</artifactId>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>2.5</version>
    </dependency>
  </dependencies>

</project>

Now no further actions are needed, jsut go navigate to the root home path and execute below maven command from a terminal to have all dependencies tree shown in front of you

mvn dependency:tree

You will see the sub-modules with slightly different versions of the spring-core artifact:

[INFO] ------------------------------------------------------------------------
[INFO] Building root 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ root ---
[INFO] dependency.management.showcase:root:pom:1.0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building child-module 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child-module ---
[INFO] dependency.management.showcase:blessed-module:jar:1.0
[INFO] \- org.springframework:spring-core:jar:3.2.8.RELEASE:compile
[INFO]    \- commons-logging:commons-logging:jar:1.1.3:compile
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building odd-module 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ odd-module ---
[INFO] dependency.management.showcase:odd-module:jar:1.0
[INFO] \- org.springframework:spring-core:jar:2.5:compile
[INFO]    \- commons-logging:commons-logging:jar:1.1:compile
[INFO] ------------------------------------------------------------------------
tmarwen
  • 15,750
  • 5
  • 43
  • 62
  • This does not quite describe my situation. What would happen in your case, if the `odd module` had `blessed-module` as its dependency? And if `odd module` didnt declare spring as its dependency? Would the end result be spring 2.5 as you would expect or would it be 3.2.8.RELEASE from the parent? Turns out that it would be 3.2.8.RELEASE! This would be fine in general but is counter intuitive if the `odd module` turns out to be an `EAR` module. You don't want to add *framework dependencies* in your EAR module but you need to have the `blessed-module` (ejb) as a dependency. – Devu Jun 05 '14 at 15:07