Gradle中如何正确将内置Configuration继承为新的自定义配置
你当前报错的核心原因是配置继承关系写反了:你声明的是nativesOS继承runtimeOnly,这仅能让nativesOS包含runtimeOnly的依赖内容,但你添加到nativesOS里的原生依赖不会自动流入runtimeOnly/testRuntimeOnly的运行时类路径,JVM运行时找不到native库自然抛出java.lang.UnsatisfiedLinkError。
问题解答
- 不需要手动配置
applicationDefaultJvmArgs传递原生库路径,这种方案需要额外实现原生依赖解压、路径注入的逻辑,冗余且容易出错。 - 正确继承自定义配置能力的方案如下:
最优方案:调整继承方向
让runtimeOnly、testRuntimeOnly继承你自定义的nativesOS配置,这样所有写入nativesOS的依赖会自动进入运行时类路径,Gradle会自动处理原生库的解压、路径注入逻辑,不需要修改任何任务配置。
修改配置创建的代码即可:
val nativesOS : Configuration by configurations.creating { isTransitive = false } // 让所有运行时配置继承自定义的nativesOS,自动同步依赖 configurations.runtimeOnly.get().extendsFrom(nativesOS) configurations.testRuntimeOnly.get().extendsFrom(nativesOS)
调整后你原有的nativesOS("org.lwjgl","lwjgl$lib", "3.2.3", classifier = "natives-windows")依赖声明不需要改动,测试、应用运行都能正常识别原生库。
备选方案:手动注入类路径
如果你确实需要保留原有的nativesOS extends runtimeOnly的逻辑,也可以手动把nativesOS的内容加入到所有需要运行时的任务类路径中:
// 测试任务加入nativesOS依赖 tasks.withType(Test::class) { useJUnitPlatform() classpath += configurations.nativesOS } // 应用启动任务加入nativesOS依赖 tasks.named<JavaExec>("run") { classpath += configurations.nativesOS }
该方案需要给所有用到运行时的任务逐一添加配置,维护成本高于第一种方案。
补充说明:你之前直接用runtimeOnly声明原生依赖时不需要修改JVM参数,是Gradle的Test、JavaExec任务默认内置了原生依赖的处理逻辑,会自动解压带natives classifier的jar包到临时目录,并自动注入java.library.path参数,不需要人工干预。
内容的提问来源于stack exchange,提问作者Liveon Phoenix

