Maven Release build on a project - artifact version number - maven

I have a maven project with the following structure
Project
- pom.xml
--- Module1
--- pom.xml for Module1
--- Module2
--- pom.xml for Module2
--- Module3
--- pom.xml for Module3
------- Module31
------- pom.xml for Module31
------- Module32
------- pom.xml for Module32
i.e. Project has it's pom.xml (packages as pom) and has modules. Each of the modules have a <parent> .. </parent> section in the individual ModuleX pom.xml file where it can be either set to artifact of "Project" (which is defined in root pom.xml) -- OR it can be set to any other project2/project3/projectN artifact.
Now, due to this, I see if Project1 root pom.xml is set to 0.0.1-SNAPSHOT and if I want to create a release candidate (non-snapshot) build "0.0.1", then I expect all the modules should generate artifact with the same version which is set in Project's root pom.xml.
I noticed, that Module2 pom.xml has a parent which is some other project (for ex: Project2) and version id of this parent is set to "0.0.7-SNAPSHOT" and Module2 pom.xml (under Project) also has some of the dependencies using Project2's artifacts.
The same case exists for Module3 and Module32 where <parent> section has a different parent (set to ProjectN where N can be any number) and has dependencies on those or any ProjectN project's artifacts.
My question:
1. If I creating a 0.0.1 (non-snapshot) build of Project, then what version id artifacts Maven will generate for the root pom, for Module1, Module2, Module3 and Module31/32?
2. How can I make sure, 0.0.1 release of Project -- generates same version# 0.0.1 for all of its modules (even though the <parent> section of those modules uses a different project**N** and have different / newer <version>..</version> value set in the <parent> section).
Thanks.

Have a look at the maven-release-plugin, it does exactly want you want. release:prepare is about verifying and updating poms, tagging the project and preparing it for the next development cycle. release:perform is about building the projects based on the tag and pushing the artifacts to a remote repository.

Related

Using Maven scm:checkin to commit changes to module projects

I have a multi-module POM file:
...
<modules>
<module>../project1</module>
<module>../project2</module>
<module>../project3</module>
...
</modules>
...
Each of the modules is itself a Maven project with its own POM. Inside each of these POMs I have the scm tag defined with the developerConnection specified like this:
<scm>
<developerConnection>scm:svn:svn://hostname:port/path/to/trunk</developerConnection>
</scm>
My goal is to run the following Maven goals/options:
versions:update-parent versions:commit scm:checkin \
-Dmessage="automated commit" -Dusername=user -Dpassword=pass
My expected results are:
The parent of each module's POM is updated to the latest released version.
The changes to each POM would be checked in to the SVN path specified in the POM for the module. E.g. project1 POM checked in using project1 <scm>/<developerConnection> path, project2 checked in using project2 path, etc.
Actual Results:
The parent of each module's POM is updated to latest released version. This works as expected.
Only the multi-module POM is checked in to SVN, none of the module POMs are checked in. This is the problem.
Is there a way to achieve the expected results above or is this something that the SCM plugin simply was not designed to do? If it is possible, how would I modify what I have in order to get the results I want?
Note: I can't change the project structure - I can't put the modules inside of the parent project, they have to remain separate.
Not sure if it's relevant but I'm using Maven 3.3.9.

Large quantity of profiles in pom.xml

I have the maven project with five separate modules each of them have pom.xml with duplicated profiles. Is there any options to move all profiles from pom to separate file?
You can put the profiles into the parent pom. They get inherited during the build:
parent pom (with all common profiles)
- module1
- module2
- module3
- module4
- module5
You need to reference the modules correctly
from parent pom using the <modules> tag
from each module reference the parent using the <parent> tag

In a multi-module build, why does a child module need to be told where to find the parent POM?

Consider the following scenario of a flat multi-module layout:
| parent-pom
| - pom.xml
| module1
| - pom.xml
Where parent-pom/pom.xml is the parent POM of all modules:
<groupId>my-group</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
...
...
<module>../module1</module>
Now, the pom.xml of module1 contains the following parent section:
<parent>
<groupId>my-group</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
</parent>
I'm starting with a clean local repository; none of the artifacts is pre-built, everything done from scratch. Trying to execute mvn install on parent-pom will result in an error, because the Maven reactor will look for my-group:base-pom in the local repository, fail (because it's not there) and then look for ../pom.xml.
Fine. My question is this: if the build of module1 is invoked through the build of parent-pom, why does Maven even have to look for the parent's pom.xml anywhere? when Maven comes to build module1, it already knows the following things:
The physical location, of the file system, of my-group:parent-pom:1.0.0.
The fact that module1 is rooted in my-group:parent-pom:1.0.0.
Why look elsewhere?
The Introduction to the POM:Project Inheritance:Example 2 told us as the following: -
The Scenario
However, that would work if the parent project was already installed in our local repository or was in that specific directory structure (parent pom.xml is one directory higher than that of the module's pom.xml).
But what if the parent is not yet installed and if the directory structure is
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
The Solution
To address this directory structure (or any other directory structure), we would have to add the <relativePath> element to our parent section.
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
As the name suggests, it's the relative path from the module's pom.xml to the parent's pom.xml.
EDITED:
The getRelativePath told us as the following
Get the relative path of the parent pom.xml file within the check out. The default value is ../pom.xml. Maven looks for the parent pom first in the reactor of currently building projects, then in this location on the filesystem, then the local repository, and lastly in the remote repo. relativePath allows you to select a different location, for example when your structure is flat, or deeper without an intermediate parent pom. However, the group ID, artifact ID and version are still required, and must match the file in the location given or it will revert to the repository for the POM. This feature is only for enhancing the development in a local checkout of that project.
I hope this may help.

Jenkins and maven multi module Projects missing artifacts

This is a simplified example of an ear project, the parent pom aggregates the EAR, the EJBs, and the jars.
I have this structure in a Maven project, stored in SVN:
parent/
|- pom.xml
|- modulA/
| |- pom.xml
|- modulB/
| |- pom.xml
modulB has a Dependency of modulA
The pom.xml have the modules section
<modules>
<module>modulA</module>
<module>modulB</module>
</modules>
And a Dependency Management section
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group</groupId>
<artifactId>modulA</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>group</groupId>
<artifactId>modulB</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
The sub-modules reference the parent
<parent>
<groupId>group</groupId>
<artifactId>parent</artifactId>
<version>0.0.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
in my PC when I compile for the first time with maven 2.2.1 (windows)
mvn clean compile
I don't have any problems
but.... when Jenkins try to compile for first time (Maven 2.2.1 Linux RedHat)
Missing:
----------
1) modulA:jar:0.0.2-SNAPSHOT
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=group -DartifactId=modulA -Dversion=0.0.2- SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=group -DartifactId=modulA -Dversion=0.0.2-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
Path to dependency:
1) modulB:ejb:0.0.2-SNAPSHOT
2) modulA:jar:0.0.2-SNAPSHOT
----------
1 required artifacts are missing.
Why????????
After that if I deploy the project from my pc to Artifactory, Jenkins doesn't have problems, because Jenkins downloads the artifact from the repository... but why does Jenkins depend on the artifacts in the repository?
:(
Thanks in Advance
EDIT:
I thought the dependencyManagement section only "defines" the dependencies, but if a submodule doesn't use the dependency, the dependency isn't added to the submodule.
I drop the dependencyManagement section and the problem in Jenkins still occurs.
It works on my PC without problems.
I hope above dependency management section is inside the parent pom. According to your requirement modulB has a Dependency of modulA. So I suggest you to include dependency in moduleB instead of having it in the parent pom. I think when it runs in first time maven is looking for both dependencies since you have mentioned in in the parent pom.Look at your project build order. First it builds module A and then B. In your case I hope you have include all other dependencies in moduleA's pom file and once it built it will deploy a jar file in to m2 repository. And then moduleB start to build and since your dependency is already in the m2 repository it wont shout and project will build successfully.
The first time you build parent project, your Jenkins user's maven repository won't have modulA installed. clean compile is then run successfully in modulA, but nothing is installed. When it is run in modulB, the dependency on modulA can't be resolved.
If your Jenkins job's goal was clean install instead of clean compile, then modulA's artifacts would be installed to the Jenkins user's repository before the modulB build begins, and all would work.
Presumably this worked on your own machine because either you had run mvn install at least once in modulA, or because your IDE's classpath resolved the problem for you.

Where placed the scm tag?

I have a little probleme with the scm tag in my pom.xml file.
My project architecture is like this:
Parent
Submodule1
Submodule2
reactor
Parent is the project which hold all maven plugins configuration, librairies version ect. It's the parent of reactor project which is the parent of all submodules.
Reactor is a pom.xml which contains tags to compile all submodules.
I would like put the scm tag on the parent pom.xml because it's the higher pom.xml. But I get an error when I want to do a "mvn release:prepare".
So I put the scm tag in the reactor pom.xml and it works.
It's good for me, it works :) but I don't understand why I need to put the scm tag in the reactor pom.
Someone can explain me this behavior ?
Thanks.
Edit:
Here is the folder structure:
root
parent
pom.xml (parent)
submodule1
pom.xml
submodule2
pom.xml
pom.xml (reactor)
Here is the interesting part of pom reactor:
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<relativePath>./parent/pom.xml</relativePath>
<version>1.0.2-SNAPSHOT</version>
</parent>
<modules>
<module>parent</module>
<module>submodule1</module>
<module>submodule2</module>
</modules>
Finally, here is the error for the release:prepare:
[INFO] Unable to tag SCM
Provider message:
The svn tag command failed.
Command output:
svn: Path 'http://10.211.55.4/svn/trunk/reactor' does not exist in revision 112
First requirement is that trunk, tags and branches folder in SVN exist which i assuem but
you have to define the scm part only in the reactor and not in the parent.
root
+-- pom.xml (reactor)
+-- parent
! +-- pom.xml (parent)
+-- submodule1
! +-- pom.xml
+-- submodule2
+-- pom.xml
Furthermore you should define the maven-release-plugin (reactor) as well with true.
The default handling of such situation is that Maven will do relative changing of the SVN paths. This will produces trouble like you have. So you have to put the information into the reactor pom NOT into the parent pom. Very important is to have only a single configuration.
Furthermore i would recommend to remove the parent and put the information into the reactor, cause you would get trouble during site generation phase.
root
+-- pom.xml (parent)
+-- submodule1
! +-- pom.xml
+-- submodule2
+-- pom.xml

Resources