IntelliJ构建LibGDX项目jar包执行时抛出VerifyError错误如何解决
错误原因
java.lang.VerifyError类型不匹配错误本质是fat jar打包过程中出现了依赖类冲突:
- 现有打包逻辑会把所有依赖解压后合并到同一个jar包,当多个依赖包含同名但版本不同的LWJGL类时,后加载的类会覆盖先加载的类,最终出现类版本不兼容的情况
- IntelliJ运行时会按照依赖声明的优先级加载类,不会出现类覆盖的问题,所以本地运行正常
解决方案
推荐使用Gradle官方的Shadow插件打包可执行单jar包,该插件会自动处理依赖冲突、重复文件、服务文件合并等问题,适配LibGDX项目的打包需求,具体配置步骤如下:
步骤1:配置根目录build.gradle
在根目录build.gradle的buildscript代码块中添加Shadow插件依赖:
buildscript { repositories { mavenLocal() mavenCentral() gradlePluginPortal() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } google() } dependencies { // 新增Shadow插件依赖 classpath 'com.github.jengelman.gradle.plugins:shadow:6.1.0' } }
步骤2:修改desktop模块的build.gradle
- 开头引入Shadow插件
- 删除原有自定义的
dist任务,新增ShadowJar配置
修改后的desktop模块build.gradle核心内容如下:
apply plugin: 'java-library' // 新增引入Shadow插件 apply plugin: 'com.github.johnrengelman.shadow' sourceCompatibility = 1.8 targetCompatibility = 1.8 sourceSets.main.java.srcDirs = ["src/"] sourceSets.main.resources.srcDirs = ["../core/assets"] project.ext.mainClassName = "com.marvelous.game.desktop.DesktopLauncher" project.ext.assetsDir = new File("../core/assets") // 原有run、debug任务直接保留即可 task run(dependsOn: classes, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath standardInput = System.in workingDir = project.assetsDir ignoreExitValue = true } task debug(dependsOn: classes, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath standardInput = System.in workingDir = project.assetsDir ignoreExitValue = true debug = true } // 新增ShadowJar配置 shadowJar { manifest { attributes 'Main-Class': project.mainClassName } // 自动排除重复文件,避免类覆盖冲突 duplicatesStrategy = DuplicatesStrategy.EXCLUDE // 合并服务注册文件,避免LWJGL初始化失败 mergeServiceFiles() // 将游戏资源打包进jar的assets目录 from(project.assetsDir) { into("assets") } // 指定输出jar的名称,可按需修改 archiveFileName.set("${appName}-all.jar") } eclipse.project.name = appName + "-desktop"
步骤3:执行打包
在项目根目录执行命令:
./gradlew desktop:shadowJar
打包完成后,可执行jar包会生成在desktop/build/libs/MarvelousMashup-all.jar,直接用java -jar命令运行即可。
可选:原有dist任务修复方案
如果不想引入Shadow插件,给原有dist任务添加冲突处理规则也能解决当前问题:
task dist(type: Jar) { manifest { attributes 'Main-Class': project.mainClassName } // 新增重复文件处理策略 duplicatesStrategy = DuplicatesStrategy.EXCLUDE dependsOn configurations.runtimeClasspath from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } // 新增合并服务文件 mergeServiceFiles() with jar }
内容的提问来源于stack exchange,提问作者Biohazard
相关产品推荐
相关产品推荐

