Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a multi-module maven build and releasing individual modules independently?

I'm currently working on optimizing a maven build of a multi-module maven project. The Project consists of about 90 Maven modules. In general there are some cross-cutting libs making up the core and then there are about 15 "application modules" making up the entire application (Which is then deployed as in a WAR)

Now in general the entire project has a major version "2.5" so when a new major release is done all "application modules" have the same version "2.5.0". So far so good.

If a module has a bug that needs to be fixed or needs improving, a new version of that "application module" should be released. So for example Module A got a bug fixed, then A.jar should be in version "2.5.1" while the rest should still be "2.5.0".

parent (2.5.0-SNAPSHOT - Module A (2.5.1-SNAPSHOT) - Module B (2.5.0-SNAPSHOT) - Module C (2.5.2-SNAPSHOT) - War (2.5.3-SNAPSHOT) <-- 3 at the end, because C had 2 re-releases and A one and was released after every module release for simplicity.

We settled for managing the artifact versions in the master pom so we don't need to update the dependency versions of each artefact after releasing one module.

So now whenever an updated "application module" is ready, we use the maven release plugin to perform the release of that module (We are releasing one module, not the entire project). So let's say we are releasing Module A in version 2.5.4 resulting in A.jar being deployed as version 2.5.4 and finishing by updating the module code to 2.5.5-SNAPSHOT.

After this is done we need to update the version in the master pom, so all modules continue to reference the right version.

Thanks to the dependencyManagement section of the master pom, if I build the War module, it automatically picks up the new version of module A.

Now comes the tricky part: As soon as all modules are released, a new version of the Web application should be released. This should contain all the unchanged Modules as well as the ones that were just released. I am currently struggling on how to do that. If I depend on the parent poms version, the release would contain SNAPSHOT versions (all one version increment too high), which I and the release plugin don't allow.

What would be the best solution for this dilemma?

I had one idea to out-source the dependency management to a separate pom, which is then imported into the master poms dependencyManagement using the "import" scope.

Is this sort of szenario a stupid Idea? Are there alternatives to developing and maintaining a large multi-module application like this? Simply having all versions in sync ans using the release plugin on the entire project is not an option as the application is big and the client applications have to load updated module versions. Some of our customers have really slow connections, so rolling out all modules every time would make them really unhappy.

Help greatly appreciated,

Chris

like image 953
Christofer Dutz Avatar asked Oct 11 '12 14:10

Christofer Dutz


People also ask

Can two Maven modules depend on each other?

Because modules within a multi-module build can depend on each other, it is important that the reactor sorts all the projects in a way that guarantees any project is built before it is required. The following relationships are honoured when sorting projects: a project dependency on another module in the build.

What is multi-module project in Maven and the setting you want to do in multi-module parent and child project what is dependency management?

A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom. The submodules are regular Maven projects, and they can be built separately or through the aggregator POM.

What are the advantages of multi-module Maven project?

Advantages of a Multi-Module ProjectIt provides a great ability to build all sub-modules only with a single command. We can run the build command from the parent module. While building the application, the build system takes care of the build order. Deployment of the applications gets very convenient and flexible.

Can a Maven project have multiple POM files?

Yes you can use Maven Profiles to manage this. Obviously you can tweak this approach to suit your needs however works best.


2 Answers

Well I came up with a solution for my problem. It's a mix of a small releaste-plugin patch and a Jenkins Plugin to handle the pretty intense commandline-configuration needed.

Description of the Release process: https://dev.c-ware.de/confluence/display/PUBLIC/Releasing+modules+of+a+multi-module+project+with+independent+version+numbers

Description of the Jenkins Plugin: https://dev.c-ware.de/confluence/display/PUBLIC/Developing+a+Jenkins+Plugin+for+the+Maven+Release+Plugin

Code of the Plugin: https://github.com/chrisdutz/jenkins-release-plugin

like image 33
Christofer Dutz Avatar answered Nov 07 '22 05:11

Christofer Dutz


First of all, it's important to realize that version numbers, while important for dependency management, are completely arbitrary. At least, the form of the version number is arbitrary (yes, I'm aware of the syntax for Maven version ranges, which I've never heard of anyone using). Some OSS projects eschew "traditional" version numbers entirely and only use SVN repository versions or dates for versioning.

One option is to not have a "project-wide" version, and rather allow each of your components to have different version numbers. I feel this is a completely acceptable solution.

Another solution is to release using snapshot dependencies. You're not "supposed" to do this, but nothing is stopping you from hard coding the snapshot version (which is incredibly verbose and timestamped). Nothing except the specter of unrepeatable builds, anyway.

If you must have all components have the same version number, I suggest incorporating a build number into the minor component of your project version.

In this approach, you leverage the Maven Build Number plugin to distinguish incremental releases within a version as described in this question: Can I set the project version with a buildnumber-maven-plugin?.

Note you would only do this in a "final release" profile that is only used by your build server (or by your build engineer).

Version Numbers plugin is also your friend here.

The final release workflow would be something like the following:

  1. Start with version 2.5.5-SNAPSHOT.
  2. mvn versions:set -DnewVersion 2.5.5.
  3. Commit and tag your release (or create a branch - whatever your strategy is here).
  4. mvn deploy -Prelease which activates your "release profile" that adds the build number to the artifact finalName.
  5. mvn versions:set -DnewVersion 2.5.5-SNAPSHOT.
  6. Commit your "post-release" version.

Increment to version 2.5.6, 2.6.0 etc. when you have a truly "major" release.

Good luck!

like image 106
noahlz Avatar answered Nov 07 '22 05:11

noahlz