Reputation: 570
Context:
The question is regarding a multi-module (maven, not Java 9 modules) Java project using maven for building it, where one module depends on the jar of another module.
Overview of the modules and some context:
What works:
mvn clean package
.What I would like to achieve:
Is there an elegant solution using maven for doing this?
Upvotes: 2
Views: 815
Reputation: 35833
In Maven, you have generally two choices:
In either case, you describe dependencies by using Maven dependencies in the pom.xml
.
Multi-module projects are usually build in one go, so compiling all the code and using the same version number for all three modules. This would violate your idea of "building against the last stable version" because you would always depend on the newest version of A when you build.
If you define three different projects, you don't have these restrictions (and C seems to be independent anyway). Two problems remain: You need to update the version of A in the dependency - which can be done with the versions plugin. And you want to construct a "one-click build". The easiest approach would probably be a pipeline in Jenkins (or whatever your build server is), but you can also write a shell script that calls Maven thrice.
Upvotes: 1
Reputation: 379
Since Maven 3.5.0-beta, there is a revision
field used to manage multi-module projects.
https://maven.apache.org/maven-ci-friendly.html
You basically need you parent pom.xml
to look like
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
</parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
</project>
And then your submodule A (child) would look like
<project>
<modelVersion>...</modelVersion>
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<!-- Make sure you have maven 3.6.0 at least for this to work -->
<version>${revision}</version>
</parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<!-- Don't put version, it's taken from the parent -->
...
</project>
And finally your module B looks like this
<project>
<modelVersion>...</modelVersion>
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>${revision}</version>
</parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
...
<dependency>
<groupId>...</groupId>
<artifactId>module-A</artifactId>
<version>${project.version}</version>
</dependency>
...
</project>
Your module C will most likely look like the module A but with no dependencies
This should make your pom work locally. If you need to deploy those, you will also need to add a flatten
plugin that will take your pom.xml
and replace the variables revision
with the actual version of your project.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You should also be able to build your projects independently using mvn clean package -pl module-A
, even though I would recommend you build A and B at the same time at least.
Upvotes: 2