【问题标题】:How to include all modules from pom project如何包含 pom 项目中的所有模块
【发布时间】:2014-10-20 17:26:02
【问题描述】:

我正在寻找一种方法来将来自另一个 pom.xml 的项目中的所有模块包含在内。所以在我的情况下,我有一个父 pom,包装设置为 pom。它包含 3 个子模块,它们在另一个 api 模块中实现我的接口。我想在 maven 中动态包含我的项目中的所有子模块。

在这种情况下,我想在另一个模块中包含连接器1、连接器2、连接器3,而不必隐式指定连接器1、2、3。

connectors - packaging: pom
   connector1 - packaging: jar
   connector2 - packaging: jar
   connector3 - packaging: jar

我尝试在我的项目中包含连接器 pom,但这不起作用。我希望用 pom 指定父包将包括子模块,但这不起作用。是否有任何解决方法可以做到这一点?

更新

这更让我恼火,因为我想简单地添加一个连接器并包含项目的所有子模块依赖 jar。这将使 pom 更易于阅读。

不必像这样注册所有子依赖项

<dependencies>
        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1-api</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1-etl</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1-persistence</artifactId>
            <version>0.0.1</version>
        </dependency>

         <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector2</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector2-api</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector2-etl</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector2-persistence</artifactId>
            <version>0.0.1</version>
        </dependency>

       <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector2-other</artifactId>
            <version>0.0.1</version>
        </dependency>
       ...
</dependencies>

这只是澄清原始问题的一个示例。它不存在,如果它确实有效,可能会产生反作用。

<dependencies>
        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1</artifactId>
            <version>0.0.1</version>
            <type>pom</type>
            <include>submodules</include>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector2</artifactId>
            <version>0.0.1</version>
            <type>pom</type>
            <include>submodules</include>
        </dependency>

</dependencies>

如果我没记错的话,我正在为一个订购系统创建一个模块化项目,其中我有一个我们内部系统将使用的通用 api (REST)。我正在创建一个路由系统,我可以在其中根据订单标准(国家、优先税等)将订单路由到单个履行中心。每个履行中心都有自己的 api(连接器)。

这个例子在原问题中被大大简化,使问题更简洁。在实际项目中,每个连接器 (1,2,3) 将是一个带有多个依赖 jar 的单独 pom。一个用于他们的客户端 api,然后是一些与我的原始 api 匹配的 etl 代码。

我不记得我是如何解决这个问题的。我想我只需要包含所有子依赖项。

【问题讨论】:

  • 你在某个地方(github?)有一个示例项目,我们可以更好地了解你到底想要做什么?
  • @RobinJonsson 问题不清楚。 include 到底是什么意思?你想要什么最终结果?你的意思是要自动填写connectors POM 中的&lt;modules&gt; 部分吗?或者别的地方?你能扩大一点吗?
  • @Tunaki 我想要的结果是能够添加新的“connectorX”包,而不必在其他地方将它们指定为依赖项。例如,我有另一个模块被打包为 WAR。我想将 WAR 的依赖项添加到“连接器”,每当我向连接器添加新的“子模块”(可能是 connector4)时,它都会自动与 WAR 文件一起打包。我的连接器没有所需的包装格式。连接器是否打包为单独的 JAR 或 uber-jar 并不重要。只要它们包含在我的 WAR 中。
  • @Tunaki 我认为这里的根本问题是我不能在connectors 模块上添加&lt;packaging&gt;jar&lt;/packaging,因为只允许pom。这意味着我无法从另一个模块添加对 connectors 的依赖并自动获取所有子模块。

标签: java maven maven-3


【解决方案1】:

一种方法是创建第四个模块,将 3 个模块“包装”为依赖项。这样你就可以依赖这个包装模块了。

connectors - packaging: pom
   connector1 - packaging: jar
   connector2 - packaging: jar
   connector3 - packaging: jar
   connectorWrapper - packaging: pom (depends on the above three)

虽然为每个连接器显式声明一个依赖关系会更有意义,尤其是它们只有三个。

替代解决方案:

一种更动态的方法(尽管在 IMO 中非常过分)是让第四个模块使用自定义 assembly descriptor 将实现模块打包到程序集中。例如,在connectorWrapper 中,你可以写一个assembly.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">

    <id>impl-modules</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}</directory>
            <includes>
                <include>pom.xml</include>
            </includes>
            <useDefaultExcludes>true</useDefaultExcludes>
        </fileSet>
    </fileSets>
    <moduleSets>
        <moduleSet>
            <useAllReactorProjects>true</useAllReactorProjects>
            <includes>
                <include>*:connector*</include>
            </includes>
            <binaries>
                <includeDependencies>false</includeDependencies>
            </binaries>
        </moduleSet>
    </moduleSets>
</assembly>

请注意,描述符告诉程序集插件:

  1. 包含当前项目reactor中的所有模块,所以当你在根项目中运行mvn clean package时,它会包含所有模块

  2. 包括实现模块(connector 模块),如具有*:connector*include 元素中指定的那样。

当然,您需要配置程序集插件以在 connectorWrapper(或您为此包装器选择的任何其他名称)中使用此描述符:

<plugins>
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <descriptors>
                <descriptor>assembly.xml</descriptor>
            </descriptors>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

然后您可以在根项目上运行mvn install 来安装程序集工件,之后您可以从其他项目依赖它:

<dependencies>
    <dependency>
        <groupId>groupId</groupId>
        <artifactId>connectorWrapper</artifactId>
        <version>...</version>
        <classifier>impl-modules</classifier> <!-- note the classifier -->
    </dependency>
</dependencies>

【讨论】:

  • 谢谢,但我的目标是让其他人能够创建实现,而无需手动将它们作为另一个依赖项添加到项目中。虽然这是一个好主意,但这相当于将其添加到另一个项目的依赖项列表中。我认为可能有一种方法可以使用程序集插件来做到这一点,但我现在正在研究。
  • 不接受这个作为答案,因为这包括另一个项目,它只是将依赖管理移动到自身。不必主动指定对新“连接器”的依赖会很好的原始问题仍然存在。
  • @RobinJonsson 实际上正如 OP 所提到的,使用汇编插件可能是可行的。更新了我的答案。
  • @AR.3 我试试看
【解决方案2】:

不完全确定它是否完全满足您的需求,但在最新的 maven 版本中,您可以在依赖项上使用范围 import

第一步是创建一个 pom,其中包含您希望包含在其他项目中的所有依赖项:

<project>

    <groupId>com.foo</groupId>
    <artifactId>connectors</artifactId>
    <version>0.0.1</version>
    <packaging>pom</packaging>

    <dependencies>
        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1-api</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.foo</groupId>
            <artifactId>connector1-etl</artifactId>
            <version>0.0.1</version>
        </dependency>

        ...
    </dependencies>    
</project>

在您想要包含您拥有的连接器的项目中:

<dependency>
    <groupId>com.foo</groupId>
    <artifactId>connectors</artifactId>
    <version>0.0.1</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

更多信息请参见Importing Dependencies

另一种方法是使用 maven 程序集插件并创建一个(巨大的)jar,其中包含您想要包含的所有类(单个 jar 包装); (为此,您还需要创建一个包含所有依赖项和程序集插件的 pom)。

【讨论】:

  • 这是否仍然意味着我必须在所有子模块的connectors 中明确指定依赖关系?
  • 是的,在父 pom 中,您仍然需要定义需要成为一部分的模块/依赖项。我认为您的目标是拥有一个可以包含在其他项目中的连接器依赖项,而不是分别包含每个子连接器。可能误会你了。
  • 没关系,看看我对原始问题的评论。问候
  • 仍然没有完全理解它(抱歉),但考虑到您上次的更新,这不适用于包括连接器 1 和 2 的所有依赖项:&lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;com.foo&lt;/groupId&gt; &lt;artifactId&gt;connector1&lt;/artifactId&gt; &lt;version&gt;0.0.1&lt;/version&gt; &lt;type&gt;pom&lt;/type&gt; &lt;scope&gt;import&lt;/scope&gt; &lt;/dependency&gt; ... &lt;/dependencies&gt;
【解决方案3】:

我会为此write my own maven plugin。从您的声誉和问题来看,您可能会在一小时内准备好一些东西。很可能比研究和尝试解决方案来做你想做的事更快。

【讨论】:

    猜你喜欢
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 2020-10-23
    • 2014-06-09
    • 2020-10-07
    相关资源
    最近更新 更多