如何发布具有项目间依赖性的Maven多模块项目?

时间:2011-03-02 11:20:58

标签: maven aggregation dependency-management maven-release-plugin multi-module

让我们说我们有3层项目。数据库,业务,Web和聚合pom。

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

所有模块都可以一起发布和分支,因此Aggregator pom配置为为所有子模块分配相同的版本。我们有以下版本:

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  

执行release:prepare时,所有版本都更新为0.1,但准备失败,因为依赖项中没有DB-0.1

一种解决方案是为每个模块创建不同的项目并逐个发布,同时使用versions:use-releases插件将依赖项更新为0.1

但我不喜欢这个想法,因为它需要大量的配置和脚本。所以,我更喜欢使用聚合并使用单个命令释放所有模块,但问题是,正如我上面所写,当发布插件尝试构建Business-0.1时,存储库中还没有DB-0.1

有没有办法管理这些项目间的依赖关系?

感谢。

UPD:

甚至安装目标都失败了。

  1. 数据库构建 - 确定(任何存储库中都没有快照或发行版本)
  2. 业务 - 失败(在存储库中找不到DB-0.1-SNAPSHOT。但它甚至不应该存在!)
  3. 我正在使用maven 3.0.2并发布插件2.1

3 个答案:

答案 0 :(得分:4)

您的项目应仅在父(项目)中定义一次版本。并让所有其他模块都有父关系。这意味着您没有聚合。你有一个多模块构建。

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

这将解决您的问题(可能您可以采取look here as an example)。

答案 1 :(得分:1)

对于多模块项目,当子快照依赖项失败时尝试此操作     release:clean release:prepare release:perform -DignoreSnapshots = true

希望它有所帮助。

答案 2 :(得分:0)

我能够使用Maven 3.3.9成功完成此操作...但让我描述一下我的案例场景:

我使用名为Liferay的Java框架,其中有一个名为Service Builder的工具,可以使用Maven构建和部署服务,其结构与您所描述的完全相同:

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

正如您所看到的,portlet app模块是使用服务作为依赖项构建的,这是一个.jar文件,它将接口与其他东西打包在一起,以使服务工作。

顺便说一句,我使用不同版本的模块对我的项目进行了此操作。我发现了一篇有趣的文章谈论这种做法:Releasing modules of a multi-module project with independent version numbers。你可以阅读摘要来得出关于版本模块是否合适的自己的结论......但是从我的角度来看,在阅读了客户的要求之后,模块的版本化应该是支持的功能似乎是合理的。 Maven没有太痛苦地实施。

在父(服务层)内运行mvn release:preparemvn:perform是可行的方法。 Maven按以下顺序进行发布构建和部署:1)父pom 2)服务依赖3)服务portlet。

Maven负责订单,这很好......但是服务依赖是基于portlet源代码构建的,目标是在父项目中运行:mvn liferay:build-service ...所以依赖性受portlet应用程序源代码的影响(听起来有点疯狂)。在我的案例中,这是一个棘手的部分。

那么我们如何为服务portlet构建和部署服务依赖项以使用它?

嗯,解决方法是使用maven-release-plugin中的配置,允许Maven在任何项目的release:perform阶段运行特定目标。我所做的是在父pom.xml(服务层)的maven-release-plugin声明中添加此配置:

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

Maven能够使用我们的首选版本号部署父级和每个子级模块(您将被要求输入它们)。

汇总回答和建议:尝试使用<goals>配置并在父级别运行mvn release:preparemvn release:perform

应按照订单部署父级和模块。

我希望这会在5年之后至少激发出类似情况的人。