使用Maven多模块项目时如何避免Java依赖地狱

时间:2017-01-19 11:14:20

标签: java maven dependencies

我已经在Java Maven多模块项目上与依赖项进行了几天的斗争。

由于疏忽太少,开发人员设法创建了一个模块,每个模块都可以自己编译,但不能作为一个整体编译。这会导致各种错误。无法找到的类,投射错误等等。这些问题的原因似乎无法确定。

我怀疑Maven在类路径上存在冲突的依赖关系。我认为我们混淆了Maven的依赖关系但是我不知道Maven如何成为一个如此糟糕的多模块项目框架。

现在我可以理解Maven在整个编译多个模块时会尝试做非常聪明的有用的事情,但是Maven中是否应该只选择将模块配置为与其他模块隔离?有这样的选择吗?为了避免这种依赖性地狱?

或者Maven是创建其他脚本的最佳实践,例如bash脚本能够通过一个命令单独编译多个模块吗?

但这也是poort解决方法的一些工具,例如SonarQube需要能够在整个代码库上运行Maven才能在SonarQube中创建单个项目。

1 个答案:

答案 0 :(得分:0)

  

这会导致各种错误。无法找到的类,投射错误等等。这些问题的原因似乎无法确定。

您可以发布错误消息吗?这样可以更轻松地分析您的问题。这可能是由依赖冲突引起的,但如果没有更多信息就很难说。

  

现在我可以理解Maven在整个编译多个模块时会尝试做非常聪明的有用的事情,但是Maven中是否应该只选择将模块配置为与其他模块隔离?有这样的选择吗?为了避免这种依赖性地狱?

我不懂。如果两个模块不相互依赖,则它们的构建将是独立的。如果一个模块依赖于另一个模块并且由于版本冲突而导致其构建失败,则无论该构建是与其他模块一起构建还是单独构建,该构建都将失败。

  

或者Maven是创建其他脚本的最佳实践,例如bash脚本能够通过一个命令单独编译多个模块吗?

Maven遵循哲学"约定优于配置",意味着您遵循惯例越多,您将拥有的配置越少,维护工作越少。创建各种脚本违背了这一理念,而不是Maven的最佳实践。

要管理多模块项目中的依赖项冲突,通常会有一个父模块,其pom.xml看起来像

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-web-api</artifactId>
                <version>6.0</version>
                <scope>provided</scope>
            </dependency>
            ...
        </dependencies>
    </dependencyManagement>

    <modules>
        ...
    </modules>
</project>

在dependendencyManagement元素中,您可以定义所使用的库的版本。这样就可以强制每个模块使用相同版本的库。

对于Maven,我经常推荐使用Java EE NetBeans IDE,因为它具有良好的依赖性可视化工具,这对于检测和消除版本冲突非常有用。 (我不知道Eclipse或IntelliJ中的类似工具)。如果在NetBeans中打开Maven项目,请单击pom.xml(在“项目”窗口中),然后选择“图形”&gt;显示图表。

我将这个工具用于两件事:

  1. 删除Maven中的传递依赖项,否则您必须管理比所需更多的依赖项。要删除传递依赖项,请右键单击图形并选择“层次”布局。不在第一行的每个依赖项都是传递依赖项,可以从pom.xml中删除。
  2. 识别传递依赖之间的冲突。 (图中的冲突以红色显示。)我通过在root pom.xml中的dependencyManagement元素中显式设置依赖项的版本来解决这些冲突。