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

Maven:生成JAR前如何干净地复制目录?

最佳实现方案:组合Maven Clean和Resources插件搞定先清后拷

哎,这个场景我之前帮团队处理过,核心问题就是maven-resources-plugin的copy-resources没自带清除逻辑,而默认的maven-clean-plugin只盯target目录。咱们把两个插件配合起来,绑定到正确的生命周期阶段就能完美解决,直接给你落地的方案:

1. 先让Clean插件清理src下的目标目录

默认Clean插件只清target/,但我们可以给它加个自定义任务,专门清理你要复制到的src子目录,而且要确保在复制之前执行。

2. 用Resources插件复制Submodule内容到src

把复制任务绑定到清理之后、编译之前的阶段,这样新复制的内容就能作为构建输入,参与后续的编译、打包流程,最终进JAR包。

完整的pom.xml配置示例

假设你的场景是:

  • Git Submodule的目标子目录路径是${project.basedir}/submodules/my-third-party-lib/static-files
  • 要复制到的src资源目录是${project.basedir}/src/main/resources/ext-resources
<build>
  <plugins>
    <!-- 第一步:清理src下的目标目录,确保旧内容全删掉 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-clean-plugin</artifactId>
      <version>3.3.2</version>
      <executions>
        <execution>
          <id>clean-target-src-dir</id>
          <!-- 绑定到process-resources阶段,确保复制前先清理 -->
          <phase>process-resources</phase>
          <goals>
            <goal>clean</goal>
          </goals>
          <configuration>
            <!-- 只清理我们指定的src子目录,不碰默认的target -->
            <filesets>
              <fileset>
                <directory>${project.basedir}/src/main/resources/ext-resources</directory>
                <includes>
                  <include>**/*</include>
                </includes>
                <!-- 保留目录本身,只删里面的内容 -->
                <followSymlinks>false</followSymlinks>
              </fileset>
            </filesets>
            <!-- 禁用默认的target清理,避免重复操作 -->
            <excludeDefaultDirectories>true</excludeDefaultDirectories>
          </configuration>
        </execution>
      </executions>
    </plugin>

    <!-- 第二步:把Submodule里的文件复制到src目录 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>
      <version>3.3.1</version>
      <executions>
        <execution>
          <id>copy-submodule-files</id>
          <!-- 同样绑定到process-resources阶段,Maven会按定义顺序先清后拷 -->
          <phase>process-resources</phase>
          <goals>
            <goal>copy-resources</goal>
          </goals>
          <configuration>
            <outputDirectory>${project.basedir}/src/main/resources/ext-resources</outputDirectory>
            <resources>
              <resource>
                <directory>${project.basedir}/submodules/my-third-party-lib/static-files</directory>
                <!-- 可以根据需求添加include/exclude规则,比如只复制特定后缀的文件 -->
                <includes>
                  <include>**/*.yaml</include>
                  <include>**/*.svg</include>
                </includes>
              </resource>
            </resources>
            <!-- 保险起见,开启覆盖,防止意外残留 -->
            <overwrite>true</overwrite>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

几个关键细节要注意

  • 生命周期顺序:两个插件都绑定到process-resources阶段,Maven会按插件在pom里的定义顺序执行,先跑Clean的清理任务,再跑Resources的复制任务,完美实现“先清后拷”。
  • Clean插件的excludeDefaultDirectories:设为true是为了让这个自定义的Clean任务只清理我们指定的src目录,不会去碰默认的target,避免和默认的Clean阶段重复操作。
  • 参与编译/打包:因为复制到了src/main/resources,Maven的默认资源处理流程会自动把这些文件同步到target/classes,最终打包进JAR;如果是需要编译的源码文件(比如Java类),只需把目标目录改成src/main/java/xxx,Maven的Compile阶段会自动处理这些新增的源码。

验证一下流程

你可以先跑这个命令测试清理+复制的流程:

mvn process-resources

跑完去看src/main/resources/ext-resources目录,旧文件肯定没了,Submodule里的新内容已经复制过来。之后再跑mvn package,这些文件会妥妥出现在最终的JAR包中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:34:19