Build child module without building parent module if there is some changes in parent pom - maven

I have a multi module project with more than 70 modules and it takes 3 Hrs to build the project with tests.
Parent pom.xml
...
<version>${revision}</version>
<properties>
<app.version>1.0</app.version
<properties>
.....
<modules>
<module>a<module>
<module>b<module>
<module>c<module>
.....
...
Child pom.xml
<parent>
<groupId>com.test</groupId>
<artifactId>parent</artifactId>
<version>${revision}</version>
</parent>
<artifactId>b</artifactId>
How to build only module b only if we change the version number in parent pom.xml

After upgrading the parent POM to a new version (and the reference to it in b's pom.xml), you could run :
mvn --projects b <maven_phase_you_want> # or mvn -pl b [...]
From Maven's help :
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path
However, this only works if the old version of your parent POM is already in your local repository, or at least is available (it have been deployed on a repository manager). Otherwise, you'll get an error because, even if specifying --projects b, Maven will try to resolve parent POM (that he won't find) for other modules a and c.

Related

Maven release plugin and using a single version in the parent pom

I have a multi-module maven project.
I hold the version in one location in the parent pom.xml as a property
and then use this in the parent pom.xml:
<project>
<artifactId>autoav</artifactId>
<version>${autoAvVersion}</version>
...
<properties>
<autoAvVersion>19.3.24-SNAPSHOT</autoAvVersion>
</properties>
</project>
And use this in the child module :
<project>
<groupId>com.mycompany.analysis</groupId>
<version>${autoAvVersion}</version>
<artifactId>analysisCore</artifactId>
<parent>
<groupId>com.mycompany.analysis</groupId>
<version>${autoAvVersion}</version>
<artifactId>autoav</artifactId>
<relativePath>../autoAV</relativePath>
</parent>
...
</project>
Maven release plugin, after running prepare+perform on the child project only (just for testing one module), changed my child pom version from
<version>${autoAvVersion}</version>
to
<version>19.3.25-SNAPSHOT</version>
So i suppose the release plugin did not think of cases using a single point version.
(By the way if i omit the version tag in the child, so it effectively gets it from the parent, the version tag without the property [19.3.25-SNAPSHOT] is still added to the child
Is there any solution to this ?

Does incrementing depending module version should increment parent module version?

I have parent module A that has module B as its dependency. If I increment version of B for just a simple bug fix, that does not change any API or break anything, do I still need to increment version of A?
Example:
A:1.10.0 --> B:2.5.0
fixing B to 2.5.1
In this case, A on Maven depends on older version of B, therefore, it seems it make sense to increate the version of A, too; so to have:
A:1.10.1 --> B:2.5.1
even though we didnt change anything in A.
Is this correct?
Yes, you are correct. If you change version of any of the dependency, you will need to build and release parent project again. This will create the new released version of your parent module A.
(Here, I am assuming that parent module A packaging type is other than pom. If the packaging type is pom, then its a different story altogether.)
Edited:
When you say parent project, you will declare its packaging as pom. It will have it's own version.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>web-project</module>
</modules>
</project>
You can also refer to some modules (child projects) in your parent pom declaration.
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>
<artifactId>web-project</artifactId>
<packaging>war</packaging>
Then for submodules there is no need to declare any version for it. Parent version will be carried over to the child project. You can override version in the child project but that's not a common practice. So your parent pom version will be incremented automatically when you release it with maven. And this new version will be carried over to child projects (modules) also.
See this - Maven project version inheritance - do I have to specify the parent version?
So parent module A, I was referring to the above case.
And maven repo - can be of two types - local repository and remote repository. Local repo is where maven looks for resolviing dependencies. This is on your machine. If maven doesn't find it there, maven retrieve those depedencies from remote repository.

How to set project version to all projects for multimodule projects (with Versions-Maven-plugin)?

I have a multi module project that goes deeper then level 1. I'm starting to use 'versions-maven-pluging'.
From my topmost parent pom I ran :
mvn versions:set -DnewVersion=13.0.2
Then I got these (sample) pom files for the topmost parent and it's first child module:
Level 0
<project>
<groupId>com.company</groupId>
<artifactId>_parent-company</artifactId>
<version>13.0.0</version>
<modules>
<module>../subproject1</module>
</modules>
</project>
Level 1
<project>
<parent>
<groupId>com.company</groupId>
<artifactId>_parent-company</artifactId>
<version>13.0.2</version>
</parent>
<groupId>com.company</groupId>
<artifactId>_parent-subproject1</artifactId>
<version>13.0.0</version>
<packaging>pom</packaging>
<modules>
<module>../subproject1.1</module>
</modules>
</project>
Level 2
<project>
<parent>
<groupId>com.company</groupId>
<artifactId>_parent-subproject1</artifactId>
<version>13.0.0</version>
</parent>
<groupId>com.company.subproject1</groupId>
<artifactId>_parent-subproject1.1</artifactId>
<version>13.0.0</version>
<packaging>pom</packaging>
</project>
When I check the module of the parent in level 0, I see the version is unchanged. Then, the version in level 1, was changed so that is ok. Finally, in the level 2 project, nothing changed.
If I get to the level 1 parent directory, I can run a command to update the child submodule of this level (but not without errors since the repo was not updated for parent 13.0.2).
mvn versions:update-child-modules
Is there a way to change everyone from first parent to the lowermost leave project? For now we are building a single version of everything so no need to create versions for each parent.
Is there a simple workflow that could make simpler? For now this is what I'm about to do:
1- Manually change the version of the topmost parent.
Run theses (in level 0 directory):
mvn versions:set -DnewVersion=13.0.2
mvn -N install
Run theses (in level 1 directory):
mvn versions:set -DnewVersion=13.0.2
Strangely enough, when I run version:set in level 1, I get the proper result. The parent and all children project POMs are set with version 13.0.2. Any idea what could I be doing wrong?

Maven version not getting updated in the .POM file

I am using Maven for building my code. I created module based maven structure like below
Parent-POM
Sub-Parent1
SP1_Child1
SP1_Child2
SP1_Child3
Sub-Parent2
SP2_Child1
SP2_Child2
SP2_Child3
All my module versions, and external dependency versions are maintained in the Parent POM. Everything works fine when I do a complete mvn install, but when I try to build one sub module like SP1_Child1, then the build fails, because it is not able to identify the version of its dependencies. I checked the maven repository in my local machine, and all my modules were installed, but the .POM files do not have the version numbers. This is probably because the where the mvn install on the Parent POM is not replacing the ${module.version} with the actual version for the child modules.
Parent-POM
<project ..>
<groupId>the.company.project</groupId>
<artifactId>Parent-POM</artifactId>
<version>1.0-SNAPSHOT</version>
...
<properties>
<module.version>1.0</module.version>
</properties>
</project>
SP1_Child1
<project ..>
<parent>
...
</parent>
<groupId>the.company.project</groupId>
<artifactId>SP1_Child1</artifactId>
<version>${module.version}</version>
...
</project>
How how can my mvn install update the versions in the .POM files in the maven repository? Or how can I run one of my sub-modules without any version errors?
The default layout of a child pom should look like this.
<project ..>
<parent>
<groupId>the.company.project</groupId>
<artifactId>SP1_Child1</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>the.company.project</groupId>
<artifactId>SP1_Child1</artifactId>
...
</project>
But you child should not define version separately only in the parent element without using a property. The version is automatically inherited to the child module from the parent. If you have the same group you also don't need to define the group in child. You can use it like this:
<project ..>
<parent>
<groupId>the.company.project</groupId>
<artifactId>SP1_Child1</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>SP1_Child1</artifactId>
...
</project>
Taking the SP1_Child1 version from parent will be very annoying for you because it will force you to install a new version of the parent for any new version of the SP1_Child1 project.
There are 2 different possible situations :
You want to be able to manage different project, with different lifecycles.
Then you specify a version in the SP1_Child1 project, and you specify the version of SP1_Child1 to be used by other projects in the parent POM (in this case, the 2 values can be different).
Your application is monolithic, even if it is organized in different modules for convenience. Then in this case, the best is to do what khmarbaise advises, keep one version for all your projects, and inherit the version from the parent.

What does the parent tag in Maven pom represent?

E.g.:
<parent>
<groupId>mycompany.trade.com</groupId>
<artifactId>mycompany.trade.</artifactId>
<version>1.1.1.0-SNAPSHOT</version>
</parent>
Does it mean that Maven will search for parent pom?
If yes, where, in which order? May be in folder up 1 level? Or in local repository or in repo?
Yes, maven reads the parent POM from your local repository (or proxies like nexus) and creates an 'effective POM' by merging the information from parent and module POM.
See also Introduction to the POM
One reason to use a parent is that you have a central place to store information about versions
of artifacts, compiler-settings etc. that should be used in all modules.
The common dependencies,Properties,constants etc can be definded in central parent project pom.xml
The main important thing is the parent project cannot be distributed and it looks quite similar to a regular "pom.xml" except that it also has a packaging tag
<groupId>com.company.demo</groupId>
<artifactId>MavenInheritance</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
The child now able to inherit this using
<parent>
<groupId>com.company.demo</groupId>
<artifactId>MavenInheritance</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
As the name suggests, we can point out a parent pom.xml file for the current pom.xml file. Doing so, dependencies, properties, constants and many more defined at the parent pom.xml file also get merged with the current pom.xml (child pom.xml) file. Say you have a parent tag in your projects pom.xml that looks like below:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
Then maven reads that parent POM from your local repository (or from repository managers like sonatype, jfrog, etc that you have configured) and creates a Resultant POM by combining the parent POM and your module’s POM.
To see the combined result use the following mvn command:
mvn help:effective-pom
This is the practice that is used in multi-modules projects where we need to inherit the dependencies from the parent projects.

Resources