Heroku部署JDA Discord机器人抛出NoSuchMethodError问题排查
问题原因
java.lang.NoSuchMethodError 是典型的编译时与运行时类版本不匹配错误。本地IntelliJ运行时IDE会优先加载你显式声明的JDA 5.0.0-alpha.12版本依赖,因此运行正常;但Heroku部署时通过maven-shade-plugin打包生成fat jar的过程中,依赖树中引入的旧版JDA类覆盖了新版本的类,旧版本GuildVoiceState.getChannel()方法返回值不是AudioChannel类型,不存在你代码调用的对应方法签名,因此抛出错误。
旧版JDA来自Lavaplayer的传递依赖,maven-shade-plugin默认处理重复类时不会自动选择高版本,直接将先扫描到的旧版本类打入最终jar包。
修复方案
- 排除Lavaplayer传递的旧版JDA依赖,修改pom.xml中lavaplayer的依赖配置:
<dependency> <groupId>com.sedmelluq</groupId> <artifactId>lavaplayer</artifactId> <version>1.3.77</version> <exclusions> <exclusion> <groupId>net.dv8tion</groupId> <artifactId>JDA</artifactId> </exclusion> </exclusions> </dependency>
- 清除Heroku构建缓存,避免旧缓存的依赖包被复用,在本地项目目录执行以下命令(需先安装Heroku CLI):
heroku builds:cache:purge -a 替换为你的Heroku应用名称
- 本地执行
mvn clean package重新打包,先在本地验证生成的jar运行无报错后,再推送代码到Heroku触发重新部署。
校验方法
如果需要确认打包后的jar内JDA版本是否正确,可以解压shade生成的target目录下的jar包,找到net/dv8tion/jda/api/entities/GuildVoiceState.class文件,执行以下命令查看方法签名:
javap -p GuildVoiceState.class
输出结果中存在public abstract net.dv8tion.jda.api.entities.AudioChannel getChannel();时,说明打包的JDA版本符合要求。
内容的提问来源于stack exchange,提问作者Furetto126
相关产品推荐
相关产品推荐

