You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven多模块项目编译错误不终止,如何阻止组装模块生成Zip?

问题:Maven多模块项目中子模块编译错误时,如何阻止assembler模块生成Zip?

我手头有个包含proj-a、proj-b、proj-c等子模块的Maven多模块项目,其中专门加了一个assembler模块,靠maven-assembly-plugin把所有子模块生成的Jar打包成Zip包。但最近发现个坑:哪怕某个子模块编译出错,父POM的构建居然不会终止,assembler模块照样生成Zip包——这就导致打包出来的文件可能缺了某个子模块的Jar,完全不符合预期。想问问怎么才能做到:只要有子模块编译失败,就直接停止整个构建,不让assembler生成错误的Zip?

下面是我的项目配置:

父POM配置

<project 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>com.my.projects</groupId>
  <artifactId>packer</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <modules>
    <module>../../com.proj-a</module>
    <module>../../com.proj-b</module>
    <module>../../com.proj-c</module>
    ...........
    <!-- assembling all jars -->
    <module>./assembler</module>
  </modules>
</project>

assembler模块POM配置

<project 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>com.my.projects</groupId>
  <artifactId>assembler</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <dependencies>
    <dependency>
      <groupId>com.my.projects</groupId>
      <artifactId>com.proj-a</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.my.projects</groupId>
      <artifactId>com.proj-b</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.my.projects</groupId>
      <artifactId>com.proj-c</artifactId>
      <version>1.0.0</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <id>make-bundles</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
            <configuration>
              <finalName>release-all-for-test</finalName>
              <appendAssemblyId>false</appendAssemblyId>
              <descriptors>
                <descriptor>/src/resources/assembly-descriptor.xml</descriptor>
              </descriptors>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

assembly-descriptor.xml配置

<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
  <id>dist-assembly</id>
  <formats>
    <format>zip</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <useTransitiveDependencies>false</useTransitiveDependencies>
      <outputDirectory>/out-put/WEB-INF/lib</outputDirectory>
      <useProjectArtifact>false</useProjectArtifact>
      <unpack>false</unpack>
    </dependencySet>
  </dependencySets>
</assembly>

解决方案

我之前也遇到过类似的问题,Maven默认会“顽强”地继续构建其他模块,哪怕某个子模块已经失败了。这里给你几个可行的解决方法,按推荐程度排序:

方法一:启用Maven快速失败模式(最简洁可靠)

Maven从3.3.1版本开始支持全局的快速失败配置,只要在父POM的<properties>里加一行配置,就能让构建在第一个失败的模块处立刻终止——这样assembler模块根本不会被执行,自然不会生成错误的Zip包。

修改父POM,添加如下配置:

<properties>
  <!-- 开启快速失败:只要有一个模块构建失败,整个构建立刻停止 -->
  <maven.build.failFast>true</maven.build.failFast>
</properties>

这个方法的好处是一劳永逸,不用修改assembler模块的任何配置,所有子模块的失败都会直接终止构建。

方法二:给assembler模块添加前置依赖检查

如果你不想全局开启快速失败,只想针对assembler模块做限制,可以用maven-enforcer-plugin在assembler打包前检查所有依赖的子模块Jar是否存在——如果子模块编译失败,对应的Jar不会被安装到本地仓库,这个检查就会失败,从而阻止assembly插件执行。

修改assembler模块的POM,在<build><plugins>中添加enforcer插件:

<!-- 先添加依赖检查插件 -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>3.3.0</version>
  <executions>
    <execution>
      <id>check-dependency-jars</id>
      <phase>prepare-package</phase> <!-- 在打包前执行检查 -->
      <goals>
        <goal>enforce</goal>
      </goals>
      <configuration>
        <rules>
          <requireFilesExist>
            <files>
              <!-- 检查每个子模块的Jar是否存在于本地仓库 -->
              <file>${settings.localRepository}/com/my/projects/com.proj-a/1.0.0/com.proj-a-1.0.0.jar</file>
              <file>${settings.localRepository}/com/my/projects/com.proj-b/1.0.0/com.proj-b-1.0.0.jar</file>
              <file>${settings.localRepository}/com/my/projects/com.proj-c/1.0.0/com.proj-c-1.0.0.jar</file>
            </files>
            <message>依赖的子模块Jar不存在,大概率是子模块编译失败了!</message>
          </requireFilesExist>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

<!-- 原来的assembly插件保持不变 -->
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>make-bundles</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <finalName>release-all-for-test</finalName>
        <appendAssemblyId>false</appendAssemblyId>
        <descriptors>
          <descriptor>/src/resources/assembly-descriptor.xml</descriptor>
        </descriptors>
      </configuration>
    </execution>
  </executions>
</plugin>

方法三:调整assembler模块的打包类型

你现在的assembler模块打包类型是pom,Maven对pom类型的模块不会严格检查依赖模块的构建状态。把它改成jar类型(哪怕模块里没有源代码),Maven就会强制要求所有依赖的子模块必须构建成功后,才会处理assembler的打包阶段。

步骤1:修改assembler模块的打包类型

<packaging>jar</packaging>

步骤2:跳过空Jar的生成(可选)

如果不想让assembler生成一个空的Jar包,可以添加maven-jar-plugin跳过默认的Jar生成:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.3.0</version>
  <executions>
    <execution>
      <id>default-jar</id>
      <phase>none</phase> <!-- 跳过默认的Jar生成阶段 -->
    </execution>
  </executions>
</plugin>

内容的提问来源于stack exchange,提问作者kurious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:01:59