如何继承多模块Maven项目及其所有好处?

时间:2012-04-20 11:46:34

标签: maven pom.xml multi-module

我找不到一个好的,可扩展的解决方案的问题:

我有一个项目可以提供给定工件的多种风格。这已被设置为多模块项目,目前有3个模块:

  • / flavour1_module
  • / flavour2_module
  • / flavour3_module

问题是我还有另外50个项目需要以相同的方式设置,即提供3种口味。

考虑的解决方案:

  1. 将已创建的多模块项目转换为所有其他50个项目的父项目
    • 缺点:它不起作用。保留父项模块的指令不会被继承,因此不会执行它们。
  2. 使用maven-archetype-plugin创建a multi-module project template,然后根据模板创建所有50个项目
    • 缺点:如果我需要flavour4,我需要手动更新所有50个项目以添加flavour4_module(并复制其内容)。不可扩展。
  3. 将所有口味的配置嵌入到单个pom中,并根据配置文件启用或禁用它们(即通过配置文件使用组合而不是通过模块继承)。然后将50个项目指向它,作为它们的父项。这将创建“内联”模块
    • 缺点:我需要在我自己的机制上实现,这些机制由开箱即用的模块提供。 (例如,在单独的目录中构建每个风味)。我也会失去模块提供的清晰分离。
  4. 任何想法如何做得很好?还有其他选择吗?

    谢谢, 卢卡斯

    修改:

    另一种选择是使用 reactor扩展maven-reactor-plugin:inject-modules 目标,该目标将从外部工件下载模块定义,并将其定义附加为普通模块。这将动态创建一个新模块。然后所有50个项目都可以将这个pom.xml作为其父项。

    配置看起来像这样(草稿):

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-reactor-plugin</artifactId>
      <version>1.0</version>
      <executions>
        <execution>
          <id>inject</id>
          <phase>initialize</phase>
          <goals>
            <goal>inject-modules</goal>
          </goals>
          <configuration>
            <modules>
              <module>
                <artifactId>flavour1_module</artifactId>
                <groupId>[ groupId ]</groupId>
                <version>[ version ]</version>
              </module>
              <module>
                <artifactId>flavour2_module</artifactId>
                <groupId>[ groupId ]</groupId>
                <version>[ version ]</version>
              </module>
              <module>
                <artifactId>flavour3_module</artifactId>
                <groupId>[ groupId ]</groupId>
                <version>[ version ]</version>
              </module>
            </modules>
          </configuration>
        </execution>
      </executions>
    </plugin>
    

    这样做会有意义吗?

    更新

    编写一个操作要执行的模块列表的插件(我上面描述的模块注入的概念)似乎无法实现,因为模块由maven核心处理,并且该机制不是为了用插件扩展。事实证明,两个插件都执行类似的操作,即操作要执行的项目列表:

    通过执行系统调用来创建maven子进程。对我而言,这不是一条路,因为这是一个非常不稳定的解决方案。确实maven-reactor-plugin与Maven3成了incompatible

    maven-invoker-plugin看起来仍然很有希望。该插件最初设计用于运行集成测试,但可以使用它来扩展,例如编译阶段。 但它需要将子pom.xml-s视为资源并在运行中进行修改。对于我在这里描述的问题,解决方案太复杂和不稳定。在构建maven模型时,我更喜欢可以在内存中运行的更轻的东西。

    所以现在我使用配置文件,试图让它们尽可能紧凑。可能有一段时间我需要再次思考这个问题。

4 个答案:

答案 0 :(得分:1)

现在,您可以使用maven-tiles插件来获得所需的行为。

使用maven-tiles,您可以在不同的poms中定义构建行为,并在任何您喜欢的地方导入

有一个工作样本附加到MNG-5102 - &gt; daddy3.zip

Maven的继承唯一的紧身夹克现已正式移除。

答案 1 :(得分:0)

在我看来,你可以为此创建多个不同的程序集描述符,并配置多个插件执行,每次执行都引用不同的描述符。您必须将项目维护为单个模块而不是多模块项目。如果您的发行版包含相同的一组类但不同的资源或库,它可以工作。

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <id>assembly</id>
                    <phase>package</phase>
                    <configuration>
                        <descriptors>
                                <descriptor>one.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
                <execution>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <id>assembly</id>
                    <phase>package</phase>
                    <configuration>
                        <descriptors>
                                <descriptor>two.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
                <execution>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <id>assembly</id>
                    <phase>package</phase>
                    <configuration>
                        <descriptors>
                                                      <descriptor>three.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
            </executions>
        </plugin>

您可以使用在那里配置的程序集来创建父pom,以便您可以从那里控制分发数量和包装更改。您的项目无需了解不同包装的详细信息。

我强烈建议将本机库保留为单独的模块,并使用存储库机制将已编译的库安装到其中。您可以使用不同的分类器来隔离平台,例如

mylib-2.0.0-win32_x86.dll
mylib-2.0.0-linux_x86.so
mylib-2.0.0-linux_x86_64.so

然后,您可以在项目中将这些库作为依赖项引用,然后将它们与您的发行版一起打包。

整体解决方案将在很大程度上取决于各种发行版的差异以及打包发行的整个过程,但我认为这样可行。

终极且更具可扩展性的解决方案是通过实施Maven插件来创建自己的包装。

答案 2 :(得分:0)

根据我的经验选项3 效果最好,但我没有必要像你需要那样扩展它 - 当我不得不这样做时我已经使用了maven-ant -plugin创建参数化的ant脚本来进行自定义。它有一些缺点 - 即同时使用ant和maven,因此实际的POM更难以理解,但它确实允许比maven更多的灵活性。

答案 3 :(得分:0)

如果您使用的是maven 3,则可以定义父pom的配置文件,并根据文件存在情况激活它们。 在子模块上,您可以通过简单地创建空文件来“继承风味”。

以下链接更好地记录了这些内容: