Gradle如何排除依赖项resources中的指定文件夹
Gradle排除依赖内指定资源文件夹的实现方案
Gradle没有提供开箱即用的依赖内部资源路径排除配置,但可以通过构建阶段的规则配置实现需求,根据你需要排除的生效阶段,可以选择对应方案:
方案1:打包阶段排除(最常用,配置简单)
如果只需要保证最终构建出的jar/war包不包含这两个文件夹的内容,直接在对应打包任务里加带范围限定的排除规则即可,不会影响本地编译时的依赖加载。
- Spring Boot可执行Jar包配置:
// 原有依赖声明保持不变 implementation "com.tobris:tobris-core:${openPlatformVersion}-SNAPSHOT" bootJar { exclude { FileTreeElement element -> String elementPath = element.path // 仅排除tobris-core依赖下的domains、views资源 element.file.absolutePath.contains("com.tobris/tobris-core") && (elementPath.startsWith("BOOT-INF/classes/domains/") || elementPath.startsWith("BOOT-INF/classes/views/")) } }
- 普通Java项目Jar包配置:
jar { exclude { FileTreeElement element -> element.file.absolutePath.contains("com.tobris/tobris-core") && (element.path.startsWith("domains/") || element.path.startsWith("views/")) } }
- Web项目War包配置:
war { exclude { FileTreeElement element -> element.file.absolutePath.contains("com.tobris/tobris-core") && (element.path.startsWith("WEB-INF/classes/domains/") || element.path.startsWith("WEB-INF/classes/views/")) } }
方案2:依赖解析阶段全局排除(彻底剔除,全构建周期生效)
如果需要在编译、资源处理、测试、打包全流程都不让这两个文件夹进入类路径,可以用Gradle的Artifact Transform能力,在依赖解析环节就把对应文件夹从依赖jar里移除,配置完成后原有依赖声明不需要修改。
import org.gradle.api.artifacts.transform.TransformAction import org.gradle.api.artifacts.transform.TransformOutputs import org.gradle.api.artifacts.transform.TransformParameters import org.gradle.api.artifacts.type.ArtifactTypeDefinition import org.gradle.api.file.FileSystemLocation import org.gradle.api.provider.Provider import org.gradle.api.tasks.InputArtifact import java.util.zip.ZipFile import java.util.zip.ZipOutputStream abstract class StripUnusedDependencyRes implements TransformAction<TransformParameters.None> { @InputArtifact abstract Provider<FileSystemLocation> getInputArtifact() @Override void transform(TransformOutputs outputs) { File sourceJar = inputArtifact.get().asFile String jarName = sourceJar.name // 仅匹配目标tobris-core依赖 if (jarName.startsWith("tobris-core-${openPlatformVersion}")) { File targetJar = outputs.file(jarName) new ZipFile(sourceJar).withCloseable { zipInput -> new ZipOutputStream(new FileOutputStream(targetJar)).withCloseable { zipOutput -> zipInput.entries().each { entry -> // 过滤掉domains、views下的所有内容 if (!entry.name.startsWith("domains/") && !entry.name.startsWith("views/")) { zipOutput.putNextEntry(entry) if (!entry.directory) { zipOutput.write(zipInput.getInputStream(entry).readAllBytes()) } zipOutput.closeEntry() } } } } } else { // 非目标依赖直接原样返回 outputs.file(sourceJar) } } } // 注册自定义转换规则 dependencies { registerTransform(StripUnusedDependencyRes) { from.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.JAR_TYPE) to.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.JAR_TYPE) } // 原有依赖声明不用修改 implementation "com.tobris:tobris-core:${openPlatformVersion}-SNAPSHOT" }
注意事项
- 禁止直接配置全局
exclude 'domains/**'这类无范围限定的规则,否则会同时把你自身项目resources目录下的同名文件夹也排除掉 - 配置完成后可以执行构建命令,解压build目录下生成的产物,检查对应文件夹是否被移除,验证规则是否生效
- 如果项目同时用到了
bootJar、jar、war多个打包任务,需要给每个用到的打包任务都配置对应排除规则,避免漏配
内容的提问来源于stack exchange,提问作者Maher Ben Taleb Ali
相关产品推荐
相关产品推荐

