包括模块二进制文件

警告

警告:使用moduleSet定义的二进制部分涉及一些棘手的考虑,这是 Maven 在多模块上下文中排序和执行项目构建的方式的结果。如果您决定使用它们,请阅读此常见问题解答条目。

注意:moduleSet部分中的新useAllReactorProjects标志允许您在多模块构建中使用来自子模块的模块二进制文件。这对于解决 Maven 的构建顺序与模块二进制文件的旧方法之间的冲突非常重要,其中程序集是从父 POM 构建的。请阅读上面的常见问题解答条目以获取更多信息,并阅读下面的文档(仔细!)以了解新方法的实际应用。

介绍

使用多模块构建的父 POM 创建程序集是常见的做法。有时,您可能希望确保此程序集还包含一个或多个模块二进制文件。

此示例演示如何在modules/<module-name>目录下包含模块的工件和依赖项。

装配描述符

首先,让我们编写一个程序集描述符来创建这个程序集。为了清楚起见,该描述符将尽可能简单,仅演示此示例描述的特征。

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
  <id>bin</id>
  <formats>
    <format>dir</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <moduleSets>
    <moduleSet>
    
      <!-- Enable access to all projects in the current multimodule build! -->
      <useAllReactorProjects>true</useAllReactorProjects>
      
      <!-- Now, select which projects to include in this module-set. -->
      <includes>
        <include>org.test:child1</include>
      </includes>
      <binaries>
        <outputDirectory>modules/maven-assembly-plugin</outputDirectory>
        <unpack>false</unpack>
      </binaries>
    </moduleSet>
  </moduleSets>
</assembly>

此描述符声明程序集 id 应为bin,输出格式为目录,并且程序集的内容不应包含在以顶级项目的 finalName 命名的目录中。

此外,它声明我们希望包含 groupId 为org.test和 artifactId 为child1的模块的工件文件,以及它的依赖工件。这些工件应包含在此模块的目录结构modules/ child1 中,因为 outputDirectory 表达式将在逐个模块的基础上进行插值。

最后,注意新的 useAllReactorProjects标志。这允许访问当前反应器(多模块构建)中的所有项目,甚至从子模块。使用此标志,现在可以使用子模块(使用适当的依赖声明排序到多模块构建过程的末尾)来生成包含模块二进制文件的程序集。

聚甲醛

现在,让我们回顾一下通过assembly:single目标启用该程序集构建所需的 POM 配置。首先,让我们看一下父 POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.test</groupId>
  <artifactId>parent</artifactId>
  <version>1.0</version>

  <packaging>pom</packaging>

  <name>Parent</name>

  <modules>
    <module>child1</module>
    <module>child2</module>
    <module>child3</module>
    <module>distribution</module>
  </modules>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>3.3.0</version>
          <configuration>
            <descriptors>
              <descriptor>src/assembly/bin.xml</descriptor>
            </descriptors>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

注意:最后一个模块 -分发- 是将在其中创建程序集的子模块。

该 POM 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  
  <parent>
    <groupId>org.test</groupId>
    <artifactId>parent</artifactId>
    <version>1.0</version>
  </parent>
  
  <artifactId>distribution</artifactId>

  <packaging>pom</packaging>

  <name>Distribution</name>
  
  <!-- NOTE: These dependency declarations are only required to sort this project to the 
       end of the line in the multimodule build. 
       
       Since we only include the child1 module in our assembly, we only need to ensure this
       distribution project builds AFTER that one...
  -->
  <dependencies>
    <dependency>
      <groupId>org.test</groupId>
      <artifactId>child1</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <id>distro-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
            <configuration>
              <descriptors>
                <descriptor>src/assembly/bin.xml</descriptor>
              </descriptors>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

此 POM 指示 Assembly Plugin在构建到达打包阶段时执行单个目标,并告诉它在执行时使用bin.xml程序集描述符。

执行!

要构建程序集,我们发出以下命令:

mvn clean package

这将确保在构建程序集目录之前删除输出目录(通常为target)。

注意:由于 Maven 2.0 的执行模型中与聚合器目标和继承层次结构有关的怪癖,我们需要在程序集调用之前显式执行包阶段,以确保所有模块都已构建。

检查输出

Maven执行完成后,应该留下以下目录结构。请记住,我们的汇编格式是dir,这就是为什么输出是目录而不是某种存档的原因。

以下是目录内容:

target/distribution/distribution-1.0-bin
`-- modules
    `-- child1
        |-- child1-1.0.jar
        `-- junit-3.8.1.jar