如何正确创建Gradle执行阶段任务?unzip_natives_os报错排查
问题原因及解决方案
自定义解压任务不生效的原因
你第二版任务写法中,val nativesJar = nativesOS.asFileTree.filter { it.name.contains("natives") }.files 定义在任务配置块的根层级,属于配置阶段执行逻辑,此时Gradle还未完成依赖解析,拿到的nativesJar是空集合,doFirst执行时自然没有文件可处理。同时你误用了Copy类型任务,没有用其内置的增量构建、输入输出追踪能力,全自定义逻辑反而提高了配置复杂度。
运行测试报java.lang.UnsatisfiedLinkError的原因
你自定义的nativesOS是独立配置,默认不会被加入到Java应用运行、测试执行的类路径或原生库扫描路径中。而runtimeOnly是Gradle Java插件内置的配置,会自动加入到运行时的依赖路径中,原生库会被自动识别加载,所以改为runtimeOnly就可以正常运行。
你有两种可选解决方案:
- 方案1:显式配置JVM启动参数
让run、test任务依赖你的解压任务,同时把解压后的原生库目录加入JVM的java.library.path参数即可,配置示例:tasks.run { dependsOn("unzip_native_os") jvmArgs += "-Djava.library.path=$buildDir/libs/natives-os/v2" } tasks.test { dependsOn("unzip_native_os") jvmArgs += "-Djava.library.path=$buildDir/libs/natives-os/v2" } - 方案2:把nativesOS关联到内置运行时配置
直接让runtimeOnly配置继承nativesOS,Gradle会自动处理原生库的加载,不需要手动解压、不需要配置JVM参数,和直接把依赖写在runtimeOnly效果一致:configurations.runtimeOnly.get().extendsFrom(nativesOS)
nativesOS无法识别BOM版本约束的原因
你仅给implementation配置添加了lwjgl-bom依赖,自定义的nativesOS配置没有关联到BOM的版本约束,所以必须手动写版本号。只要给nativesOS也添加BOM依赖即可自动继承版本:
dependencies { val lwjglBom = platform("org.lwjgl:lwjgl-bom:3.2.3") implementation(lwjglBom) // 给nativesOS也添加BOM依赖 nativesOS(lwjglBom) listOf("", "-assimp", "-openal", "-opengl", "-glfw").forEach { lib -> implementation("org.lwjgl:lwjgl$lib") // 不需要手动指定版本,BOM已经生效 nativesOS("org.lwjgl:lwjgl$lib") { classifier = LWJGL.lwjglNatives } } }
修复后的解压任务示例
用Copy任务内置能力实现,支持增量构建,不会触发配置阶段提前解析依赖:
tasks.register<Copy>("unzip_native_os") { group = "zip" // 绑定输入为nativesOS配置下的原生jar,Gradle自动追踪依赖变更 from(nativesOS.asFileTree.matching { include("**/*natives*.jar") }.map { zipTree(it) }) // 绑定输出目录 into("$buildDir/libs/natives-os/v2") }
内容的提问来源于stack exchange,提问作者Liveon Phoenix
相关产品推荐
相关产品推荐

