We are attempting to move several multi-module applications to maven, and having some problems.
Each module is stored independently in cvs. We have manifest files for each application, which list the modules required for that application (and optionally the version). Not all modules are in maven form.
So application 'customer_care' has the following manifest:
<manifest>
<module id="MY_api"/>
<module id="custcare_webapp"/>
</manifest>
Similarly, the application 'core batch' has a manifest like this:
<manifest>
<module id="MY_api"/>
<module id="core"/>
<module id="batch"/><!--NB this is a non-maven module -->
</manifest>
I have started 'mavenising' our code, so the MY_api project has a pom.xml with dependencies defined, including one on another internal code module 'central_config'. I have specified version RELEASE.
This all works fine, until I need to create a frozen manifest. I can specify a version for each module:
<manifest>
<module id="MY_api" version="0.123.0"/>
<module id="core" version="0.456.0"/>
<module id="batch" version="0.789.0"/><!--NB this is a non-maven module -->
</manifest>
BUT this build is not reproducible, because the version of the 'centralconfig' dependency in MY_api is 'RELEASE'. So if someone releases a new version of 'centralconfig', then next time we build this frozen manifest, it's different.
So why don't we use hard-coded versions of dependencies like central-config? Because then, we would have to update perhaps 10 or 20 pom files every time someone updates centralconfig to a new version. Everything which depends on central config, and everything which depends on that, would need its pom.xml updating and to be re-released. Not only is this lots of work, I don't know how I could programmatically and reliably identify every module which declares a dependency on central config.
Could I define 'centralconfig.version' in one place, and then refer to it in all my modules? If so, where should I do this? I don't know much about parent poms but I feel they might provide a solution.
It seems that using a parent pom is the way to go. But according to this question: Can maven projects have multiple parents? , it's not possible for a maven child project to have multiple parents.
So then how can the MY_api module be a child of both custcare_webapp and core_batch?
I've concluded that maven doesn't meet my requirements, and we've gone back to using our 12-year old home-grown solution build using ant and CVS.
One other option that is often better than a parent-structure for managing versions is to import dependencies.
To illustrate how this works you create one project that only contain a pom specifying the versions to use for all your modules:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>module-versions</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>2</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Then, in all your projects that need to have dependencies to anyhing that you have hard coded versions for you import this project in the following manner:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>module-versions</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
This way you only have to change the module-versions
project anytime you release a new version of anything you have a dependency to.
This way you can have multiple "module-versions"-projects to split things up a bit.
Of course, you still have the problem that all project's that want to use the new version must also be released in turn, but that is the cost of using released dependencies in Maven.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With