How to release Maven multi-module project with int

2019-04-08 16:22发布

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

3条回答
Animai°情兽
2楼-- · 2019-04-08 16:31

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.

查看更多
虎瘦雄心在
3楼-- · 2019-04-08 16:34

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).

查看更多
走好不送
4楼-- · 2019-04-08 16:37

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.

查看更多
登录 后发表回答