如何将LWJGL模块与自定义Java模块分离?
问题解决:LWJGL模块反向导出错误
问题描述
使用LWJGL 3.3.1、Gradle 8.0.2开发程序,IDE为IntelliJ 2022.2.1,通过PowerShell运行Gradle。编译过程正常,但运行程序时提示我的模块包含LWJGL包,且LWJGL包反向导出到我的模块。查看生成的压缩包发现自定义Jar与LWJGL的Jar处于同一目录。
提供的代码
build.gradle
plugins { id 'java' id 'application' id 'org.beryx.jlink' version '2.25.0' } group 'ch.l1chorpe' version '1.0.0' project.ext.lwjglVersion = "3.3.1" project.ext.lwjglNatives = "natives-windows" repositories { mavenCentral() } dependencies { implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion") implementation "org.lwjgl:lwjgl" implementation "org.lwjgl:lwjgl-assimp" implementation "org.lwjgl:lwjgl-cuda" implementation "org.lwjgl:lwjgl-glfw" implementation "org.lwjgl:lwjgl-opencl" implementation "org.lwjgl:lwjgl-opengl" implementation "org.lwjgl:lwjgl-stb" runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives" } jar { duplicatesStrategy(DuplicatesStrategy.EXCLUDE) manifest { attributes 'Main-Class': 'ch.l1chorpe.fractalscl.Main' } from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } } sourceCompatibility = '19' targetCompatibility = '19' application { mainModule = 'ch.l1chorpe.fractalscl' mainClass = 'ch.l1chorpe.fractalscl.Main' } jlink { imageZip = project.file("${buildDir}/distributions/FractalsCL-${version}.zip") options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages'] launcher { name = 'app' } } jlinkZip { group = 'distribution' }
module-info.java
module ch.l1chorpe.fractalscl { requires org.lwjgl; requires org.lwjgl.glfw; requires org.lwjgl.opengl; exports ch.l1chorpe.fractalscl; }
解决方案
核心问题
你的jar任务中添加了from { configurations.runtimeClasspath.collect... },这会把所有运行时依赖(包括LWJGL的Jar)解压后合并到你的自定义Jar中,导致你的模块Jar包含了LWJGL的包(如org.lwjgl)。Java模块系统要求每个包只能属于一个模块,此时你的模块和LWJGL模块都持有同一包,就触发了反向导出的错误。
修改步骤
修改
jar任务,仅打包自身代码
将jar块修改为:jar { duplicatesStrategy(DuplicatesStrategy.EXCLUDE) manifest { attributes 'Main-Class': 'ch.l1chorpe.fractalscl.Main' } // 移除将依赖内容打包进自身Jar的代码 }利用jlink分发模块化应用
你已经配置了org.beryx.jlink插件,该插件会自动处理模块化依赖,生成包含所有必要模块的运行镜像。直接运行./gradlew jlinkZip任务,生成的压缩包中的启动器会正确加载模块路径,无需手动处理依赖Jar的位置。
验证
修改后重新编译并运行jlinkZip,生成的压缩包中,你的模块Jar和LWJGL模块Jar会被正确组织在模块化镜像结构中,运行启动器时不会再出现模块冲突错误。
内容的提问来源于stack exchange,提问作者l1chorpe
相关产品推荐
相关产品推荐

