Ant转Maven - 多个构建目标

54

我有一个正在转换为Maven的Ant构建项目。然而,该Ant构建项目有两个构建目标 - 一个构建整个应用程序,另一个从其中一些文件(仅少量文件)中构建一个JAR文件。在Ant中,可以很容易地具有多个构建目标来处理此问题,但是我正在尝试确定在Maven中处理此问题的最佳方法。

我可以将文件的子集拆分成第二个项目,并且它将有自己的POM文件。然后第一个项目可以依赖于此项目。然而,由于文件的子集非常小(少于10个),因此似乎为此完全创建一个新项目可能有点过头了。

是否有其他处理方式?

3个回答

80

您可以使用配置文件实现这一点...

如果您真的想要使用两个独立的配置文件并自定义JAR插件以包含和排除类和包名称模式,您可以通过在POM中添加以下内容轻松实现此目的:

<profiles>
  <profile>
    <id>everything</id>
    <build>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <classifier>everything</classifier>
            <includes>
              <include>**/*</include>
            </includes>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
  <profile>
    <id>only-library</id>
    <build>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <classifier>only-library</classifier>
            <excludes>
              <exclude>**/Main*</exclude>
            </excludes>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

附言:如果这看起来需要大量配置,Polyglot Maven对Groovy POM的支持即将准备就绪。它将大大减少代码行数。

您需要将此代码放在pom.xml的末尾(在项目元素内),它会添加两个配置文件。第一个配置文件“everything”只是为了演示配置。这个“everything”配置文件是不必要的,因为它只是重复默认的JAR插件jar目标执行的行为。第二个配置文件“only-library”排除了任何以“Main”文本开头的包中的任何类。调用这些配置文件:

mvn package -Peverything
mvn package -Ponly-library

我对《Maven实战》第6章中提供的示例应用进行了测试,运行这两个命令之一将在${basedir}/target中生成带有分类器的JAR文件。由于JAR插件的jar目标绑定到默认maven生命周期中的package阶段,因此这两个配置文件将修改此插件的配置。

或者,您可以使用两个JAR插件执行...

如果您需要创建两个JAR而不使用配置文件,则可以将JAR插件的jar目标多次绑定到打包生命周期阶段,并为每个配置的执行使用不同的配置。如果您配置了两个单独的执行,则每个执行都有一个执行特定的配置块,因此您可以为每个执行提供唯一的标识符和包含/排除模式。

以下是您将使用的构建元素,以将两个自定义JAR添加到生命周期阶段“package”中。在具有包装“jar”的项目上执行此操作将导致运行三次jar目标。一次作为默认生命周期绑定,然后两次用于两个自定义分类的JAR。

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
          <execution>
            <id>only-library</id>
            <goals><goal>jar</goal></goals>
            <phase>package</phase>
            <configuration>
              <classifier>only-library</classifier>
              <excludes>
                <exclude>**/Main*</exclude>
              </excludes>
            </configuration>
          </execution>
          <execution>
            <id>everything</id>
            <goals><goal>jar</goal></goals>
            <phase>package</phase>
            <configuration>
              <classifier>everything</classifier>
              <includes>
                <include>**/*</include>
              </includes>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

如果你不是在谈论将不同的类集成到每个构件中,那么你需要使用Maven Assemblies。如果你想了解组装的细节,可以查看《Maven:完全参考指南》末尾列出的章节。坦白地说,我认为这一特定章节并不是一个很好的入门参考;事实上,我已经收到了许多关于这一章节几乎无法阅读的报告(我们正在努力修复它)。如果你想使用组装,我建议你查看Maven Assembly Plugin的文档。在左侧导航菜单中,你会看到示例组装描述符的列表。
免责声明:请不要这样做。如果你正在创建两个具有不同类集的JAR包,我强烈建议你将项目拆分为两个相互依赖的模块。

虽然你可以使用配置文件来完成这个过程,但将项目拆分为两个(实际上是三个)部分会更容易。从长远来看,随着你的应用程序规模的扩大,你将面临挑战。你需要负责确定手动列出的类和被分配到每个分类JAR包中的包。

有一个简单的父项目引用两个独立模块的开销很小。如果您查看免费的"Maven by Example"书籍,我们将展示如何在单模块和多模块项目之间进行转换。第3-5章专注于单模块项目,第6章向您展示如何将这些单模块组件组合成更大的多模块项目。
更多信息:
您的问题涉及以下主题,以下链接将为每个主题提供更多详细信息:
Maven JAR插件: http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html 多模块Maven项目: Maven by Example的第6章Maven:完全参考的3.6.2节

Maven生命周期(如果您的打包方式是"jar",则绑定到package):《Maven by Example》第3.5.2节“核心概念”《Maven:完全参考》第4章

Maven组件:首先,查看Maven组件插件网站,然后查看《Maven:完全参考》第8章以获取一些繁琐(几乎太繁琐)的详细信息。


5
哇,很棒的回答,汤姆。大加赞成。 - Pascal Thivent
感谢您提供详细的答案。我想避免使用包模式。如果其他开发人员进来,不一定知道需要使用的模式,这似乎会带来维护上的麻烦。 - Jeff Storey

23

你的第一个想法是正确的。将这两个部分拆分为两个项目。

Maven的理念是每个项目应该只构建一个工件(jar、war或其他类型)。

你可能可以通过某种方式将两个工件放在一个Maven项目中构建,但这是一种非正式的方法。

你可以在Maven中调用Ant,所以如果你真的想这么做,那我建议你开始查看Maven Ant插件。它的artifact id是“maven-antrun-plugin”。


5

您有两个选择:

如果子集仅是一组资源,则不必将其作为单独的模块。

如果项目始终依赖于以统一方式打包的子集,则该子集是成为一个模块的好选择。

如果子集以多种不同的“风味”重新打包,则应为每个“风味”定义组件集,并使用“分类器”限定构件名称,参见Maven 坐标

最后,您可以使用配置文件来确定哪些组件集将被生成。默认配置文件可能仅在开发过程中创建所需的初始构件“风味”。
“完整”配置文件可能会为最终部署生成所有“风味”变体的构件。


1
我使用程序集来打包我构建的工件以及依赖项、脚本等。在构建文件子集时,使用程序集是常见的做法吗?还是将文件子集拆分为自己的项目更好的做法? - Jeff Storey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接