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
相关产品推荐
相关产品推荐

