我的项目由5个子项目组成。一个是战争,另外四个是罐子。基本上,war项目需要所有4个jar项目及其依赖项。
我可以删除依赖关系以具有类似war-> A-> B-> C-> D的东西。每个子项目都会添加它们的外部依赖项(spring,struts,hibernate),这样最终战争就能获得运行所需的一切。
这看起来非常有条理和正方形,但后来我问自己这是否非常实用,可以进行更改。
想象一下,我必须更改项目D中的一行代码,而不更改其Maven依赖项。我显然必须重新发布项目D,但后来我必须重新发布项目C,B,A和战争只是为了反映他们的pom文件中的这一变化。这可能很长而且很烦人,特别是如果您必须快速发布新版本以修复生产中的某些内容。
我可以让战争依赖于所有4个项目,所以我只需要在war pom文件中更改项目D版本号。但后来我有项目A间接取决于项目D 1.0和战争指定项目D 1.1。我认为战争直接依赖会赢得那种情况不会吗?
这会使新的战争版本更快,但它也会弄乱我的子项目依赖项,因为它们会过时。
处理这种情况的可行方法是什么?
答案 0 :(得分:3)
您的问题没有简单的答案。
如果你确实有一系列传递依赖(A-> B-> C-> D),那么独立释放链上的每个模块并不是一个糟糕的选择。虽然它很繁琐,但您的嵌套依赖项很可能是简单的lib jar,并且不会经常看到更改。希望你不会被迫经常经历这个过程。假设它与更新log4j并且所有模块都需要更新的情况相同。
要考虑的另一件事是你的WAR依赖。是的,Maven将自动为您提取依赖关系,但明确声明已知的依赖关系通常是一个好习惯,因此您可以为每个模块自己指定版本号。这意味着A直接取决于D和其他人。不幸的是,如果您的版本号有冲突,正如您所描述的那样,那么您正在寻找类路径上的问题。如果你真的需要这样做,maven确实允许你明确地排除传递依赖:
<project>
...
<dependencies>
<dependency>
<groupId>my.project</groupId>
<artifactId>module-B</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>my.project</groupId>
<artifactId>module-C</artifactId>
</exclusion>
<exclusion>
<groupId>my.project</groupId>
<artifactId>module-D</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>my.project</groupId>
<artifactId>module-C</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>my.project</groupId>
<artifactId>module-D</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>my.project</groupId>
<artifactId>module-D</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
...
</project>
以下是描述这些可选依赖项和排除项的documentation。
你真的需要独立发布B,C和D吗?如果没有,请考虑在模块的根目录中使用Aggregator pom.xml文件。这将允许您在整个模块中使用SNAPSHOT版本,然后立即释放这些版本。这是我们团队管理多模块项目的方式。使用SNAPSHOT依赖项可确保您使用在需要这些工件时刚刚构建的版本。
答案 1 :(得分:1)
在没有WAR的情况下,您是否实际独立发布任何项目A到D?如果没有,我认为您当前的设置没有任何问题。您应该绝对在整个项目中使用相同版本的任何模块。否则你打开了通往类加载器地狱的大门 - 相信我,你不想到达那里: - (
为了简化发布,maven-release-plugin可能对您有所帮助。
答案 2 :(得分:1)
现在最好的答案是使用gradle,这是最好的蚂蚁和maven。我从来没有真正喜欢过maven,但gradle有很多共同的概念,但是它更像是蚂蚁,因为它很灵活,所以在gradle中你的问题没有一个简单的答案;)。