Check Dependency Convergence for single artifact - java

Consider the following Maven project, having a parent and two modules.
parent
<?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>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<module>module1</module>
<module>module2</module>
</modules>
</project>
module1
<?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>
<artifactId>module1</artifactId>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>3.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>module2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
module2
<?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>
<artifactId>module2</artifactId>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
</project>
Module 1 has a dependency on weld-se-core, which in turn has a dependency on jakarta.enterprise.cdi-api. Module 2 has itself a dependency on jakarta.enterprise.cdi-api. Furthermore, module 1 has dependencies to junit-jupiter and mockito-junit-jupiter, both of which have a dependency on junit-jupiter-api, but unfortunately in different versions. Please consider this as an example. In my real project this is some private third-party dependency with a much larger dependency-tree, which neither can nor want to change.
As both modules are under my control, I want to make sure that when weld-se-core is updated in module 1, jakarta.enterprise.cdi-api in module 2 is updated accordingly. I tried using the maven-enforcer-plugin with the following rules
<dependencyConvergence/>
<requireSameVersions>
<dependencies>
<dependency>jakarta.enterprise:jakarta.enterprise.cdi-api</dependency>
</dependencies>
</requireSameVersions>
Problem is: requireSameVersions does not break the build, when the versions of jakarta.enterprise.cdi-api don't match while dependencyConvergence shows me all errors, not only the one concerning jakarta.enterprise.cdi-api.
The message when using the dependencyConvergence rule is as follows (abbreviated)
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (enforce-cdi-same-version) # module1 ---
[WARNING]
Dependency convergence error for jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.2 paths to dependency are:
[...]
+-com.example:module1:0.0.1-SNAPSHOT
+-org.jboss.weld.se:weld-se-core:3.1.4.Final
+-jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.2
and
+-com.example:module1:0.0.1-SNAPSHOT
+-com.example:module2:0.0.1-SNAPSHOT
+-jakarta.enterprise:jakarta.enterprise.cdi-api:2.0.1
[WARNING]
Dependency convergence error for org.junit.jupiter:junit-jupiter-api:5.6.2 paths to dependency are:
[...]
+-com.example:module1:0.0.1-SNAPSHOT
+-org.junit.jupiter:junit-jupiter:5.6.2
+-org.junit.jupiter:junit-jupiter-engine:5.6.2
+-org.junit.jupiter:junit-jupiter-api:5.6.2
and
+-com.example:module1:0.0.1-SNAPSHOT
+-org.mockito:mockito-junit-jupiter:3.3.3
+-org.junit.jupiter:junit-jupiter-api:5.4.2
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.DependencyConvergence failed with message:
Failed while enforcing releasability. See above detailed error message.
The first Warning is wanted, the second one is unwanted.
Question: Is there any way to ensure dependency convergence only for a specific set of dependencies?

Related

Maven: why are dependencies declared in parent pom not inherited by child pom?

When I declare a dependency in a parent pom like -
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
</dependency>
</dependencies>
</project>
above i have declared spring-core as a dependency for parent pom.
Now in child pom, i am importing the parent pom -
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</project>
Now on looking at the dependencies inherited by child pom, there are none. Should NOT the spring-core jar be inherited by child project in all cases. As the parent pom directly depends on this jar and is it not passed on/inherited by child projects.
Note: This question is not about dependency management and versions
I understand dependencyManagement, which is to ensure that a set of projects have the same version and scope of a depencency.
There is a difference between placing a parent tag and Bill of materials (importing the pom in the dependency management section)
Using <parent> is a "real inheritance" in maven. You define this tag on the child pom and by that you will get all the dependencies defined in the parent pom automatically (also properties and plugins).
The Bill of Materials on the other hand (This is how its called in the official documentation) doesn't import any dependencies by itself, however it allows to avoid specifying the versions of the dependencies in the pom of your application, because you define them in this BOM.
So to answer your question, you should really rewrite the child pom as:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</project>
Your child pom is a standalone pom because you didn't specified a parent. You define a parent by adding this tag :
<parent>
<groupId>yourpackage</groupId>
<artifactId>yourartifactid</artifactId>
<version>version</version>
</parent>
In your case, this block should do the trick :
<parent>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
I know that your question was not about depedencies management; but for people that would not know the difference I'll write some words about that.
Note that by importing your pom in <dependenciesManagement> you don't have any impact given that it only defines intentions of use but not concrete import. The <dependencies> contains the concrete imports and it's only its content that you can use in your application.

Why Maven fails to manage version of war type dependency?

We have a multi module project where we define several dependencies in parent pom under dependencyManagement tag to manage dependencies version.
It works fine for several modules but one.
Parent pom
<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>
<groupId>my.org.product</groupId>
<artifactId>product-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<parade-web.version>2.0.0</parade-web.version>
<!-- other properties -->
</properties>
<modules>
<module>../ProductWeb</module>
<!-- other modules -->
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>my.org.parade</groupId>
<artifactId>ParadeWeb</artifactId>
<version>${parade-web.version}</version>
</dependency>
<!-- other dependencies -->
</dependencies>
</dependencyManagement>
</project>
ProductWeb pom
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>my.org.product</groupId>
<artifactId>product-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../productparent</relativePath>
</parent>
<artifactId>ProductWeb</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency> <!-- 'dependencies.dependency.version' for my.org.parade:ParadeWeb:jar is missing. -->
<groupId>my.org.parade</groupId>
<artifactId>ParadeWeb</artifactId>
<type>war</type>
</dependency>
<!-- other dependencies -->
</dependencies>
</project>
If I add <version>${parade-web.version}</version> in my ProductWeb pom, NetBeans warns me that
Overrides version defined in DependencyManagement. The managed version is 2.12.2-RELEASE.
The only difference between this dependency and the other is the war type, but I don't get why dependency management fails to sets its version.
UPDATE
I managed to omit version tag but I needed to add <type>war</type> on both parent and child.
I don't understand. Does parent try to resolve dependency version looking for a war but then doesn't pass it through its children?
Add <type>war</type> to the dependencyManagement. This should do the trick.

pom use a common dependency for 3 applications Spring-mvc

I have a dependency called "general-lib" which will be modified and used by 3 teams.
Admin, Child-ABC and Child-XYZ are those 3 projects. Those 3 apps
deployed in same server.
Child-XYZ and Child-ABC are communicating to
Admin app frequently.
When we change general-lib version, I want
that Child apps also should use same version what admin app uses.
Finally that particular dependency version should be managed at super application.
is there any to do that ? Please let me know if I need to explain better.
You can define a BOM (Bills of Materials) where you can move the dependecyManagement for the common artifacts and then declare it as a parent in your 3 projects. This is an example of BOM:
<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>
<groupId>your.group.id</groupId>
<artifactId>whatever-BOM</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<general-lib.version>1.0.2</general-lib.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your.groupid</groupId>
<artifactId>general-lib</artifactId>
<version>${general-lib.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
For more details on BOM, you can read the article Spring with Maven BOM that even if it's related to Spring, it will explain in a detailed way what are BOMs and how to use them.
Ohter possibility, is to define those 3 projects as a module of a higher level project and manage in this one the dependencyManagement.
<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>
<groupId>your.group.id</groupId>
<artifactId>whatever</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>Admin</module>
<module>Child-ABC</module>
<module>Child-XYZ</module>
</modules>
<packaging>pom</packaging>
<properties>
<general-lib.version>1.0.2</general-lib.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your.groupid</groupId>
<artifactId>general-lib</artifactId>
<version>${general-lib.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

Why does Maven not find/figure out the version of the artifact in the child pom?

I am restructuring a projects and wonder why i need to specify the version of an artifact in a child when it should be known...
Just to give an overview before i get into the details.
I have the following:
A library called generalUtils.
It has a parent, bom and a few 'other' artifacts.
In it, each of the 'other' artifacts parent, is the parent artifact, whose parent is the bom artifact
A library called web.
It depends on the generalUtils library.
it has a parent, bom, and a few 'other' artifacts.
In it, each of the 'other' artifacts parent, is the parent artifact, whose parent is the bom artifact.
In the DependencyManagement.Dependencies section of the parent artifact, I import the generalUtils bom artifact
I don't have to specify the version of any of the generalUtils artifacts in project web. Everything is fine.
However...
I also have a library called monitor.
It depends on both the generalUtils and web libraries.
it has a parent, bom, and a few 'other' artifacts.
In it, each of the 'other' artifacts parent, is the parent artifact, whose parent is the bom artifact.
In the DependencyManagement.Dependencies section of the parent artifact, I import both the generalUtils and web bom artifacts.
I don't have to specify the version of any of the generalUtils artifacts in any of the project monitor artifacts. However, if i don't specify the version of any of the web project artifacts. i get an error message.
webApi is one of the artifacts in the web library project and i'm getting this error message:
[INFO] Scanning for projects...
[ERROR] The build could not read 2 projects -> [Help 1]
[ERROR]
[ERROR] The project com.retx.monitor:eventCollector:1.0.6.InSync (C:\TFSROOT\Monitor_1.0.6.In\EventCollector\pom.xml) has 1 error
[ERROR] 'dependencies.dependency.version' for com.retx.web:webAPI:jar is missing. # line 74, column 15
[ERROR]
[ERROR] The project com.retx.monitor:eventNotifier:1.0.6.In (C:\TFSROOT\Monitor_1.0.6.In\EventNotifier\pom.xml) has 1 error
[ERROR] 'dependencies.dependency.version' for com.retx.web:webAPI:jar is missing. # line 78, column 15
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
...
It's complaining that in two of the 'other' artifacts in the monitor project (eventCollector and eventNotifier) i have not specified a version for a web library artifact (webAPI)
Why is it complaining only about the web artifact and not about the generalUtils artifacts even though they are import exactly in the same way?
I'm using maven 2.0.11 for generalUtils and web libraries, but the monitor library is built using maven 3.0.3.
Now the actual pom files:
Project library generalUtils bom artifact's 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.retx.general.utils</groupId>
<artifactId>bom</artifactId>
<version>1.0.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>bom</name>
<description>Bill of Materials for general utils</description>
<properties>
<generalUtils.version>1.0.3-SNAPSHOT</generalUtils.version>
<!-- wildfly third-party dependencies versions -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.retx.general.utils</groupId>
<artifactId>configuration</artifactId>
<version>${generalUtils.version}</version>
</dependency>
<!-- a few others similar to the above -->
</dependencies>
</dependencyManagement>
</project>
Project library web bom artifact's 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.retx.web</groupId>
<artifactId>bom</artifactId>
<version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>bom</name>
<description>Bill of Materials for Web</description>
<properties>
<webRoot.version>3.0.0-SNAPSHOT</webRoot.version>
<!-- bring in needed boms from other streams -->
<generalUtils.version>1.0.3-SNAPSHOT</generalUtils.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.retx.web</groupId>
<artifactId>webApi</artifactId>
<version>${webRoot.version}</version>
</dependency>
<!-- a few others similar to the above -->
</dependencies>
</dependencyManagement>
</project>
Finally the monitor library artifacts, from parent down...
monitor library bom artifact 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.retx.monitor</groupId>
<artifactId>bom</artifactId>
<version>1.0.6.In</version>
<packaging>pom</packaging>
<name>bom</name>
<description>Bill of Materials for Monitor Modules</description>
<properties>
<!-- this stream -->
<monitor.version>1.0.6.In</monitor.version>
<!-- bring in needed boms from other streams -->
<webRoot.version>3.0.0-SNAPSHOT</webRoot.version> <!-- wildfly changed from 2.7.0.1-SNAPSHOT -->
<generalUtils.version>1.0.3-SNAPSHOT</generalUtils.version> <!-- wildfly changed from 1.0.2-SNAPSHOT -->
<!-- wildfly third-party dependencies versions -->
<!-- ... -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.retx.monitor</groupId>
<artifactId>eventCollector</artifactId>
<version>${monitorRoot.version}</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.retx.monitor</groupId>
<artifactId>eventNotifier</artifactId>
<version>${monitorRoot.version}</version>
<type>ejb</type>
</dependency>
</dependencies>
</dependencyManagement>
</project>
monitor library parent artifact pom.xml:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.retx.monitor</groupId>
<artifactId>bom</artifactId>
<version>1.0.6.In</version>
<relativePath>bom/pom.xml</relativePath>
</parent>
<artifactId>monitor-root</artifactId>
<packaging>pom</packaging>
<name>monitor-root</name>
<description>Monitor Modules</description>
<dependencyManagement>
<dependencies>
<!-- import the generalUtils library bom -->
<dependency>
<groupId>com.retx.general.utils</groupId>
<artifactId>bom</artifactId>
<version>${generalUtils.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- import the web library pom -->
<dependency>
<groupId>com.retx.web</groupId>
<artifactId>bom</artifactId>
<version>${webRoot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>${xalan.version}</version>
</dependency>
<!-- other third part dependencies ->
</dependencies>
</dependencyManagement>
<!-- the rest is not relevant ->
</project>
pom.xml of the eventCollector artifact in the monitor library:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.retx.monitor</groupId>
<artifactId>monitor-root</artifactId>
<version>1.0.6.In</version>
<relativePath>..</relativePath>
</parent>
<groupId>com.retx.monitor</groupId>
<artifactId>eventCollector</artifactId>
<packaging>ejb</packaging>
<name>EventCollector</name>
<dependencies>
<!-- dependency from the generalUtils library ->
<dependency>
<groupId>com.retx.general.utils</groupId>
<artifactId>utils</artifactId>
</dependency>
<!-- dependency from the web library ->
<dependency>
<groupId>com.retx.web</groupId>
<artifactId>webAPI</artifactId>
</dependency>
<!-- third party artifacts-->
<dependency>
<groupId>org.jboss.spec.javax.jms</groupId>
<artifactId>jboss-jms-api_2.0_spec</artifactId>
</dependency>
<!-- other third party artifacts-->
</dependencies>
<!-- the rest is not important -->
</project>
The relevant error message disappears if i just add the version to the webApi dependency in the above xml, like:
<!-- dependency from the web library ->
<dependency>
<groupId>com.retx.web</groupId>
<artifactId>webAPI</artifactId>
<version>${webRoot.version}</version>
</dependency>
Shouldn't maven be able to deduce the version of webAPI from the info in the parent artifact?
(Note that the generalUtils dependency does not need the version to be specified here... )
I think what you need is:
parent pom :
<?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>
<groupId>com.greg</groupId>
<artifactId>ear-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>ear-example</name>
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Then in each of the children/modules you have a dependency with no version, i.e. the version is inherited from the parent :
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.greg</groupId>
<artifactId>ear-example</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module1</artifactId>
<packaging>war</packaging>
<name>example-war Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>example-war</finalName>
</build>
</project>

Use of environment variable in POM.xml doesn't work

I am trying to pull out the version number of the POM and all the dependencies to a environment variable. For example:
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven- 4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>example-assembly</artifactId>
<name>example-assembly</name>
<properties>
<current.version>${env.CURRENTVERSION}</current.version>
</properties>
<dependencies>
<dependency>
<groupId>com.example.demo</groupId>
<artifactId>exceptions</artifactId>
<version>${current.version}</version>
</dependency>
<dependencies>
<packaging>war</packaging>
<version>${current.version}</version>
</project>
With the above setup, when I run mvn clean command I am getting following error:
dependencies.dependency.version for example-assembly:war must be a valid version but is '${env.CURRENTVERSION}'
Any idea about what could be the issue?
Note: I am running maven in windows OS
There is a better alternative for updating Versions in pom.xml than using environment variables inside pom.xml: Versions Maven Plugin. This allows you to change pom.xml using maven command line.
Sample scenario
Project Structure:
+ P (Parent - Version 1.0.0-SNAPSHOT)
-- C1 (Child Project 1 - Version 1.0.0-SNAPSHOT)
-- C2 (Child Project 2 - Version 1.0.0-SNAPSHOT also depends on C1)
Task
You want to change version in all pom.xml files to 1.0.1-SNAPSHOT
Parent pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Parent</name>
<packaging>pom</packaging>
<modules>
<module>c1</module>
<module>c2</module>
</modules>
</project>
Child Project 1 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c1</artifactId>
<name>Child Project 1</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
</project>
Child Project 2 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c2</artifactId>
<name>Child Project 2</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>sample</groupId>
<artifactId>c1</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Command
Command to set new version in all pom.xml files
mvn -B -DnewVersion=1.0.1-SNAPSHOT versions:set
In case new version is represented by environment variable CURRENTVERSION
mvn -B -DnewVersion=$CURRENTVERSION versions:set
Here -B means --batch-mode (so new version won't be prompted on console)
Resultant files would be
Parent pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.1-SNAPSHOT</version>
<name>Parent</name>
<packaging>pom</packaging>
<modules>
<module>c1</module>
<module>c2</module>
</modules>
</project>
Child Project 1 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c1</artifactId>
<name>Child Project 1</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
</project>
Child Project 2 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c2</artifactId>
<name>Child Project 2</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>sample</groupId>
<artifactId>c1</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
The variable you define has the scope in the same pom.xml only and cannot be used in any other pom.
If you want to define the variable globally define it in settings.xml of maven.
Define the variable env.CURRENTVERSION somewhere in the the same pom, root pom or settings.xml
or else provide the exact version value in its place.
<properties>
<current.version>'your correct version'</current.version>
</properties>
e.g.
<properties>
<current.version>1.0.0</current.version>
</properties>

Categories

Resources