如何在Gradle中调整JAR依赖顺序解决Paper-API与CraftBukkit冲突
Gradle依赖优先级配置:仅指定包使用特定依赖
问题描述
当前依赖配置(包含其他未列出的依赖):
dependencies { compileOnly("com.destroystokyo.paper:paper-api:$paperApiVersion") compileOnly(files("libs/craftbukkit-1.12.2.jar")) }
需求:仅从craftbukkit-1.12.2.jar中加载org.bukkit.craftbukkit包及其子包的类,其余所有类均使用paper-api的实现——因为craftbukkit的其他包类会与paper-api产生冲突。
执行./gradlew shadowJar构建JAR时,出现多个方法找不到的错误:
e: /plugin/src/main/kotlin/com/hakim/common/bukkit/command/RegisterCommandRuntime.kt: (12, 49): Unresolved reference: getCommandMap e: /plugin/src/main/kotlin/com/hakim/infrastructure/request/model/CommandHandlerRequest.kt: (22, 18): None of the following functions can be called with the arguments supplied: public abstract fun sendMessage(p0: Array<(out) String!>!): Unit defined in org.bukkit.entity.Player public abstract fun sendMessage(p0: String!): Unit defined in org.bukkit.entity.Player e: /plugin/src/main/kotlin/com/hakim/network/ui/command/HubCmd.kt: (19, 64): Unresolved reference: toCenterLocation e: /plugin/src/main/kotlin/com/hakim/statefulblocks/domain/StatefulBlock.kt: (23, 35): Unresolved reference: toBlockLocation
路径已修改
确认:上述缺失的方法仅存在于paper-api的对应类中,craftbukkit库无相关实现。需要调整依赖优先级,让Gradle优先从paper-api加载除org.bukkit.craftbukkit外的所有类,仅该包使用craftbukkit的实现。
Gradle版本:
------------------------------------------------------------ Gradle 7.4.2 ------------------------------------------------------------ Build time: 2022-03-31 15:25:29 UTC Revision: 540473b8118064efcc264694cbcaa4b677f61041 Kotlin: 1.5.31 Groovy: 3.0.9 Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM: 11.0.16 (Ubuntu 11.0.16+8-post-Ubuntu-0ubuntu122.04) OS: Linux 5.15.0-48-generic amd64
解决方案
方法1:包级过滤依赖
直接对craftbukkit-1.12.2.jar进行包过滤,仅保留需要的org.bukkit.craftbukkit包,排除其他所有包,避免与paper-api冲突:
dependencies { compileOnly("com.destroystokyo.paper:paper-api:$paperApiVersion") compileOnly(files("libs/craftbukkit-1.12.2.jar")) { // 排除所有包,再单独包含目标包 exclude(group = "*", module = "*") include(module = "craftbukkit-1.12.2", group = "*") { include("org/bukkit/craftbukkit/**") } } }
方法2:强制依赖优先级+包过滤
如果方法1不生效,可通过resolutionStrategy强制paper-api的优先级,再配合包过滤:
configurations.all { resolutionStrategy { // 强制org.bukkit下的类优先使用paper-api版本 force("com.destroystokyo.paper:paper-api:$paperApiVersion") } } dependencies { compileOnly("com.destroystokyo.paper:paper-api:$paperApiVersion") compileOnly(files("libs/craftbukkit-1.12.2.jar")) { include("org/bukkit/craftbukkit/**") } }
方法3:调整ShadowJar配置(按需)
如果需要打包依赖类,可在shadowJar任务中明确指定仅包含craftbukkit的目标包:
tasks.shadowJar { dependencies { // 排除paper-api(因为是compileOnly,通常不需要打包) exclude(dependency("com.destroystokyo.paper:paper-api:$paperApiVersion")) // 仅打包craftbukkit的指定包 include(dependency(files("libs/craftbukkit-1.12.2.jar"))) { include("org/bukkit/craftbukkit/**") } } }
验证步骤
- 执行
./gradlew dependencies --configuration compileOnlyClasspath查看依赖树,确认org.bukkit下非craftbukkit的包仅来自paper-api,org.bukkit.craftbukkit来自craftbukkit-1.12.2.jar。 - 重新执行
./gradlew shadowJar,检查是否仍存在方法找不到的错误。
内容的提问来源于stack exchange,提问作者HaKIM
相关产品推荐
相关产品推荐

