How to release Maven multi-module project with inter-project dependencies?
Asked Answered
P

3

8

Lets say we have 3 layers project. DB, Business, Web and aggregating pom.

Project  
|-DB  
| |-pom.xml  
|-Business  
| |-pom.xml  
|-pom.xml

All modules are ment to be released and branched together, so Aggregator pom is configured to assign the same version to all submodules. We have the following versions:

DB-0.1-SNAPSHOT  
Business-0.1-SNAPSHOT which depends on DB-0.1-SNAPSHOT  
Web-0.1-SNAPSHOT which depends on Business-0.1-SNAPSHOT  

When doing release:prepare, all versions updated to 0.1, but prepare fails because there is no DB-0.1 in dependency yet.

One solution is to create different projects for every module and release them one by one while using versions:use-releases plugin to update dependency to 0.1

But I do not like this idea because it requires a lot of configuration and scripting. So, I prefer to use aggregation and release all modules with single command, but the problem is, as I wrote above, when release plugin tries to build Business-0.1 there is no DB-0.1 in repository yet.

Is there any way to manage these inter-project dependencies?

Thanks.

UPD:

even install goal fails.

  1. DB Build - OK (no snapshot nor release version is in any repository)
  2. Business - Failure (DB-0.1-SNAPSHOT not found in repository. But it's even not supposed to be there yet!)

I'm using maven 3.0.2 and release plugin 2.1

Paulo answered 2/3, 2011 at 11:20 Comment(3)
You have listed Business and DB as modules of the parent POM, right? And you are running release:prepare only on the parent POM, right? The functionality you describe works out-of-the-box, normally.Virtuosic
Yes it runs IF Business depends on some older version of DB that is already in repository. But if you try to reference the new version which cannot be in repository as it it wasn't even built yet, then no, it doesn't work..Paulo
It doesn't need to be in the repo - Maven will look in its "reactor" (ie currently-building modules) first.Virtuosic
T
4

your project should define the version only in the parent (project) only once. And let all other modules have a parent relationship. This means you don't have a aggregation. You have a multimodule build instead.

Project  
|-pom.xml (version 0.1-SNAPSHOT)
|-DB  
| |-pom.xml (parent: ..)
|-Business  
| |-pom.xml (parent:..)

This will solve your problem (May be you can take a look here as an example).

Tuba answered 2/3, 2011 at 13:26 Comment(6)
Every module has reference to the parent '<parent> <artifactId>parent-test</artifactId> <groupId>com.lookin2.test</groupId> <version>0.0.14-SNAPSHOT</version> </parent>' And I configured a release plugni to set each module with parent version. The problem is that Business has dependency on version of DB that is not in repository yet. If I set this dependency to some older version which is in repository already, then all works fine. I only have problem when trying to release new version of entire project.Paulo
Which Maven version are you workign with? Can you give the pom snippets in particular with the referencing the DB dependency?Tuba
This answer doesn't address how one module (eg Business) can depend on another (eg DB) and have that dependency updated automatically during the release process.Journalist
Agree, this answer doesn't address the question at all.Pheidippides
@Paulo Why did you accept this answer? Perhaps you can elaborate on how it solved your problem?Len
I'd say it's the right answer but the explanation could be more clear. By leaving the version only in the parent, the the dependencies will be updated before the sub-modules start to build, which will make the reactor handle the dependencies so that DB is released and built before Business.Kiruna
P
2

I was able to succeed at doing this using Maven 3.3.9...but let me describe my case scenario:

I work with a Java framework called Liferay, where there is a tool called Service Builder that can build and deploy services using Maven with the exact structure as you described:

Service Layer
|-pom.xml (version 1.12.0-SNAPSHOT)
|-Service Portlet
| |-pom.xml (version 1.16.0-SNAPSHOT)<---   
|-Service                               | Artifact dependency
| |-pom.xml (version 1.5.0-SNAPSHOT)-----

As you can see, the portlet app module is built with the service being a dependency, which is a .jar file that packs interfaces among other things for the services to work.

By the way, I did this with my project using modules of different versions. I found an interesting article talking about this practice: Releasing modules of a multi-module project with independent version numbers. You can read the abstract to draw your own conclusions about if versioning modules is appropriate or not... but from my point of view, after reading the demands of the Client, it seems reasonable to me that versioning of modules should be a feature supported by Maven without being too painful to implement.

Running mvn release:prepare and mvn:perform inside the parent (Service Layer) was the way to go. Maven makes the release building and deployment in the following order: 1) parent pom 2) service dependency 3) service portlet.

Maven took care of the order, and that is nice...but the service dependency is built based on the portlet source code, with a goal being run in the parent project: mvn liferay:build-service...so the dependency is affected by the source code of the portlet app (sounds a little crazy). That was a tricky part in my case.

So how do we get the service dependency built and deployed for the service portlet to use it?

Well, the solution for this was using a configuration within the maven-release-plugin that allows Maven to run particular goals in the release:perform phase within any of the projects. What I did is adding this configuration in the maven-release-plugin declaration in the parent pom.xml (Service Layer):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-release-plugin</artifactId>
  <version>2.5.2</version>
  <configuration>
   <goals>clean liferay:build-service deploy</goals>
  </configuration>
</plugin>

And Maven was able to deploy the parent and each of the children modules with our preferred version numbers (you will be asked to input them).

Summarized answer and recommendation: try using the <goals> configuration and run mvn release:prepare and mvn release:perform at the parent level

Parent and modules should be deployed following the order.

I hope this inspires someone in a similar situation at least, after 5 years.

Pang answered 19/7, 2016 at 21:8 Comment(0)
E
2

For the multi module project, when it fails for child snapshot dependency try this release:clean release:prepare release:perform -DignoreSnapshots=true

Hope it helps.

Ethiopian answered 21/4, 2017 at 7:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.