Java with Maven:如何使模块B依赖于模块A的jar?

时间:2019-05-21 23:14:32

标签: java maven intellij-idea jar dependencies

上下文:

问题是关于一个使用maven进行构建的多模块(maven,而不是Java 9模块)Java项目,其中一个模块取决于另一个模块的jar。

模块概述和一些上下文:

  • A:一个编译为jar的库。
  • B::客户端应用程序,它依赖于 A 的jar;编译为可执行jar。
  • C:服务器应用程序,既不依赖于 A 也不依赖于 B ;编译为可执行jar。
  • 我只能使用Java 8,因此不能使用Java 9模块。
  • 使用的IDE是IntelliJ IDEA Ultimate。

有效的方法:

  • 使用mvn clean package将模块构建到三个单独的jar中(对于 B C 可以执行)。
  • 将软件包从 A 模块导入到模块 B 的类中(不是我想要的)。
  • 将模块 A 的依赖项添加到 B 的pom.xml中(我不知道这有什么作用...)。

我想要实现的目标:

  • 我想向模块 B 的pom.xml中的模块 A 构建的 jar 添加依赖项。
  • 我想从模块 B 的类中的模块 A 的jar中导入公共类和接口(通过将其作为依赖项添加到pom.xml中)并且无需手动复制jar)。 -> B 的开发和调试应仅依赖于 A 的最新稳定版本,并且不应与同时在 A
  • 库上进行开发而中断
  • 整个构建过程应通过执行一个Bash脚本(一次)来完成。
  • 构建项目应按顺序执行以下步骤:
    1. 将模块 A 构建到jar中(如果不可避免,还可以构建 B )。
    2. 使用步骤1中生成的jar将
    3. B(或重建)模块 B 构建为可执行的jar。
    4. 在构建过程中随时
    5. 构建模块 C

是否有使用maven的优雅解决方案?

2 个答案:

答案 0 :(得分:2)

自Maven 3.5.0-beta起,有一个revision字段用于管理多模块项目。

https://maven.apache.org/maven-ci-friendly.html

您基本上需要父母pom.xml看起来像

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
  </parent>
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>${revision}</version>
  ...

  <properties>
    <revision>1.0.0-SNAPSHOT</revision>
  </properties>
</project> 

然后您的子模块A(子级)看起来像

<project>
  <modelVersion>...</modelVersion>
  <parent>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <!-- Make sure you have maven 3.6.0 at least for this to work -->
    <version>${revision}</version> 
  </parent>
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <!-- Don't put version, it's taken from the parent -->
  ...
</project>

最后,您的模块B看起来像这样

<project>
  <modelVersion>...</modelVersion>
  <parent>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>${revision}</version> 
  </parent>
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  ...
  <dependency>
    <groupId>...</groupId>
    <artifactId>module-A</artifactId>
    <version>${project.version}</version>
  </dependency>
  ...
</project>

您的模块C很可能看起来像模块A,但没有依赖性

这应该使您的pom在本地工作。如果需要部署这些插件,则还需要添加一个flatten插件,该插件将使用pom.xml并将变量revision替换为项目的实际版本。

 <build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>flatten-maven-plugin</artifactId>
      <version>1.1.0</version>
      <configuration>
        <updatePomFile>true</updatePomFile>
        <flattenMode>resolveCiFriendliesOnly</flattenMode>
      </configuration>
      <executions>
        <execution>
          <id>flatten</id>
          <phase>process-resources</phase>
          <goals>
            <goal>flatten</goal>
          </goals>
        </execution>
        <execution>
          <id>flatten.clean</id>
          <phase>clean</phase>
          <goals>
            <goal>clean</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
  </build>

即使我建议您至少同时构建A和B,您也应该能够使用mvn clean package -pl module-A独立构建项目。

答案 1 :(得分:1)

在Maven中,通常有两种选择:

  1. 定义三个项目A,B和C。
  2. 定义一个包含A,B和C作为模块的多模块项目。

在任何一种情况下,您都可以通过在pom.xml中使用Maven依赖关系来描述依赖关系。

多模块项目通常是一次性构建的,因此编译所有代码并为所有三个模块使用相同的版本号。这将违反您的“根据最新的稳定版本进行构建”的想法,因为在构建时,您始终依赖于最新版本的A。

如果定义了三个不同的项目,则没有这些限制(并且C似乎还是独立的)。仍然存在两个问题:您需要更新依赖项中A的版本-可以使用版本插件来完成。您想要构建“一键构建”。最简单的方法可能是Jenkins(或任何构建服务器)中的管道,但是您也可以编写一个调用Maven三次的Shell脚本。