使用Gradle Shadow构建Forge JAR时,如何确保引入所有依赖及传递依赖?
问题:Gradle Shadow打包Forge模组时SLF4J依赖缺失触发NoClassDefFoundError
运行Minecraft服务器时出现以下错误:
java.lang.NoClassDefFoundError: org/slf4j/Logger at net.dv8tion.jda.internal.utils.IOUtil.<clinit>(IOUtil.java:35)
使用Gradle Shadow构建Minecraft Forge模组JAR包时,目标依赖JDA已被包含在生成的JAR中,但SLF4J(JDA的传递依赖)未被打包进去。原本预期Shadow会自动引入所有依赖(包括依赖的依赖),但尝试更换SLF4J包版本、JDA版本,以及调整build.gradle配置后问题仍存在。
使用版本:Gradle 7.3.3,Shadow 7.0.0,Forge 1.16.5-36.2.34
当前build.gradle内容(已移除模组特定信息):
buildscript { repositories { maven { url = 'https://maven.minecraftforge.net' } mavenCentral() } dependencies { classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true } } plugins { id 'com.github.johnrengelman.shadow' version '7.0.0' } apply plugin: 'net.minecraftforge.gradle' // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. apply plugin: 'eclipse' apply plugin: 'maven-publish' apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'java-library' repositories { mavenCentral() maven { name 'm2-dv8tion' url 'https://m2.dv8tion.net/releases' } } shadowJar { dependencies { include(dependency('org.slf4j:slf4j-api:1.7.36')) include(dependency('net.dv8tion:JDA:4.3.0_298')) } } dependencies { minecraft 'net.minecraftforge:forge:1.16.5-36.2.34' implementation 'org.slf4j:slf4j-api:1.7.36' implementation 'net.dv8tion:JDA:4.3.0_298' }
解决方法
1. 调整ShadowJar配置,自动包含传递依赖
手动指定include会忽略依赖的传递链,改为基于runtimeClasspath配置打包所有依赖,同时排除Forge已提供的类避免冲突:
shadowJar { // 基于runtimeClasspath包含所有依赖(含传递依赖) configurations = [project.configurations.runtimeClasspath] // 排除Forge自带的核心库,防止重复打包冲突 exclude 'net/minecraftforge/**' exclude 'com/google/common/**' // 重定位第三方包到模组专属路径,避免和其他模组的依赖冲突 relocate 'org.slf4j', '你的模组包名.lib.slf4j' relocate 'net.dv8tion.jda', '你的模组包名.lib.jda' }
2. 用shadow依赖配置标记需打包的内容
将implementation替换为shadow配置,让Shadow自动识别需要打包的依赖及其传递依赖,同时添加SLF4J的实现类(JDA需要具体的SLF4J实现才能运行):
dependencies { minecraft 'net.minecraftforge:forge:1.16.5-36.2.34' // 使用shadow配置替代implementation,明确标记需要打包的依赖 shadow 'org.slf4j:slf4j-api:1.7.36' shadow 'net.dv8tion:JDA:4.3.0_298' // 添加SLF4J的简单实现,否则JDA运行时会找不到日志实现 shadow 'org.slf4j:slf4j-simple:1.7.36' }
3. 让Forge构建任务使用Shadow生成的JAR
默认Forge的build任务会使用普通jar任务的输出,需要修改任务依赖,确保最终打包的是Shadow生成的JAR:
// 让build任务依赖shadowJar tasks.build.dependsOn tasks.shadowJar // 禁用默认jar任务,避免输出冲突 jar { enabled = false } // 去掉ShadowJAR默认的-shadow后缀,让输出文件名符合Forge模组规范 shadowJar { classifier = '' }
内容的提问来源于stack exchange,提问作者Richard Hedges
相关产品推荐
相关产品推荐

