Gradle多模块项目clean后build时WEB-INF.zip缺失问题排查
你的问题核心是任务依赖关系不明确和Gradle任务执行逻辑配置错误,导致clean后build时,WEB-INF.zip的生成与复制时机晚于jar包的打包过程,甚至源文件还未生成就执行了复制操作。以下是具体问题点和修复步骤:
1. packageWebapp 未依赖 webapp 的 dist 任务
packageWebapp任务需要复制webapp生成的RestSanatan-WEBAPP-${webapp.version}.zip,但未明确依赖webapp的dist任务。clean后build时,packageWebapp可能在webapp的dist任务执行前就运行了,此时源文件不存在,而Gradle的Copy任务默认不会因源文件不存在报错,只会跳过复制,导致WEB-INF.zip未被加入资源目录。
修复:
在restsanatan-server的packageWebapp任务中添加依赖,并优化路径写法:
task packageWebapp(type: Copy) { dependsOn webapp.dist // 或写全路径 ":restsanatan-webapp:dist" from webapp.buildDir.file("distributions/RestSanatan-WEBAPP-${webapp.version}.zip") into buildDir.file("resources/main/org/projectsanatan/restsanatan") rename "RestSanatan-WEBAPP-${webapp.version}.zip", "WEB-INF.zip" }
2. jar/shadowJar 任务未依赖 packageWebapp
虽然你给assemble添加了packageWebapp的依赖,但assemble是聚合任务,包含jar、shadowJar等子任务。默认情况下,jar的执行顺序可能早于packageWebapp,导致jar包打包时,WEB-INF.zip还未复制到资源目录。而不执行clean时,jar包已存在,后续复制的资源可能被shadowJar等任务包含,所以能正常出现。
修复:
取消注释restsanatan-server中的以下代码,确保jar和shadowJar在packageWebapp完成后执行:
jar.dependsOn(packageWebapp) shadowJar.dependsOn(packageWebapp)
3. webapp 的 assemble 任务配置错误
restsanatan-webapp的assemble任务直接在闭包中写了mkdir和copy逻辑,这部分代码会在Gradle配置阶段执行,而非任务执行阶段。clean后build时,配置阶段创建的build/generated目录会被后续的clean任务删除,导致dist任务找不到源文件。
修复:
将assemble的执行逻辑放到doLast闭包中,确保只在任务执行阶段运行:
assemble.doLast { mkdir("build/generated") copy { from "src" into "build/generated/public" include "**" } copy { from "views" into "build/generated/views" include "**" } }
额外优化建议
- 根项目的
distZip和distJar任务可直接依赖:restsanatan-server:distZip和:restsanatan-server:shadowJar,而非整个:build,减少不必要的任务执行。 - 所有路径尽量使用Gradle的
file()方法,避免硬编码绝对路径,提升跨平台兼容性。
内容的提问来源于stack exchange,提问作者EkaSaffronGaruda

