28

我很难设置一组相互依赖的相关 Maven 项目。

这是我的简化案例:

pom.xml     -- parent pom
\base\
    pom.xml
    src\main\java\Base.java     -- this is just a simple class
\derived\
    pom.xml
    src\main\java\Derived.java  -- this is a simple class that needs Base class to compile successfully, and has a main function

我的目标是:

  1. 能够在我的机器上编译所有项目:
    • mnv clean compile在\中成功
  2. 能够在我的机器上编译一个项目:
    • mnv clean compile在 \base\ 和 \derived\ 中成功(尽管这可能无法按设计工作:Inter Project Dependencies in Maven
      [编辑:找到这个答案:base 需要在本地发布,然后在编译中派生:即在 \基础,做mvn clean compile install而不是做只是做mvn clean compile。完成此操作后,mvn clean compile在 \derived 中进行操作即可。尽管如此,在不触及全局状态(即无需安装基础)的情况下这样做会很棒——所以如果有人知道实现这一点的方法,请将其添加为答案]
  3. 能够直接从源代码树在我的机器上运行派生项目(mvn exec:run 或等效项):
    • mvn exec:run在 \derived\ 应该编译(如果需要)并运行derived.jar
  4. “共享组件”用例:将基础工件推送到共享存储库,其他人可以将其作为 maven 依赖项(即编译时依赖项)使用:
    • mvn clean compile ???会将其推送到 ~/.m2/config.xml 中指定的共享存储库
  5. “图像目录”用例:将派生的工件及其依赖项推送到本地目录,可以通过“java -jar ...”在其中运行,也可以公开为 ftp/http 共享以供其他人获取. 即,像这样的用例:
    • mvn clean compile ???会将derived.jar 和依赖项(如base.jar)推送到~/.m2/maven.repo/.../derived 或等效项,然后我可以cd ~/.m2/maven.repo/.../derived并java -jar derived.jar运行它。
    • mvn clean compile ???将 base.jar 推送到 ~/.m2/maven.repo/.../base (或derived.jar 到其相应的目录),它已经通过本地 Web 或 ftp 服务器作为下载点公开。

如何实现上述目标?

这是父pom的相关部分:

...
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo</groupId>
<artifactId>parentpom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<name>parentpom</name>

<modules>
    <module>base</module>
    <module>derived</module>
</modules>
...

这是 base pom.xml 中的相关部分:

...
<parent>
    <groupId>com.foo</groupId>
    <artifactId>parentpom</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.base</groupId>
<artifactId>base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>base</name>
...

这是派生的 pom.xml 的相关部分:

...
<parent>
    <groupId>com.foo</groupId>
    <artifactId>parentpom</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.derived</groupId>
<artifactId>derived</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>derived</name>

<dependencies>
    <dependency>
        <groupId>com.foo</groupId>
        <artifactId>base</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

...

预先感谢您的帮助。

4

1 回答 1

40

您的父 pom 看起来不错,但您的模块/派生 pom 不:有几个问题会产生一些问题等。

首先,您为派生/基本模块使用不同的 groupId。如果你有一个多模块构建,你不应该这样做。此外,派生/基础的版本由父级继承,不应设置为显式,这意味着您应该具有以下内容:

<modelVersion>...</...>
...
<parent>
    <groupId>com.foo</groupId>
    <artifactId>parentpom</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>base</artifactId>
<packaging>jar</packaging>

<name>base</name>

groupId 通常是继承的。但有时你有大量的模块,这些模块可能是子模块的子模块,这会导致这样的结构:

+--- parent (pom.xml)
       +--- mod1 (pom.xml)
              +--- mod11 (pom.xml)
              +--- mod12 (pom.xml)
       +--- mod2 (pom.xml)

在这种情况下,mod1 本身就是一个 pom 打包模块:

<modelVersion>...</...>
...
<groupId>com.company.project<groupId>  
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<modules>
  <module>mod1</module>
  <module>mod2</module>
</modules>

模组1:

<parent>
    <groupId>com.company.project<groupId>  
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<groupId>com.company.project.mod1</groupId>
<artifactId>mod1</artifactId>
<packaging>pom</packaging>

<modules>
  <module>mod11</module>
  <module>mod12</module>
</modules>

模组11:

<parent>
    <groupId>com.company.project.mod1</groupId>
    <artifactId>mod1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>mod11</artifactId>
<packaging>pom</packaging>

<modules>
  <module>mod11</module>
  <module>mod12</module>
</modules>

如果您需要在模块之间建立依赖关系,则解决方案是:

<parent>
    <groupId>com.company.project.mod1</groupId>
    <artifactId>mod1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>mod11</artifactId>
<packaging>jar</packaging>

<dependencies>
  <dependency>
    <!-- This shouldn't be a dep which is packaging: pom -->
    <groupId>${project.groupId}</groupId>
    <artifactId>mod2</artifactId>
    <version>${project.version}</version>
  </dependency>

</dependencies>    

要编译包含所有子模块的整个项目,只需转到父文件夹并:

mvn 清洁包

将编译等。如果您只想编译一个项目,您可以通过(从父级)执行此操作:

mvn -pl mod1

仅当您以前安装过整个项目一次时才有效。另一种解决方案是:

mvn -am -pl mod1

为了使其他人可以访问工件,最简单的解决方案是安装存储库管理器并执行以下操作:

mvn 部署

所有其他人都可以使用和工件作为 SNAPSHOT 依赖项。

于 2012-09-03T07:20:39.597 回答