LWJGL检测到不支持的JNI版本导致程序崩溃求助
问题:LWJGL报「Unsupported JNI version detected」并崩溃,附带代码优化请求
问题背景
使用Java结合GLFW与OpenGL进行游戏开发,基于LWJGL 3.3.1 build 7,运行时出现「Unsupported JNI version detected」报错,随后程序崩溃。已尝试更换JDK版本、更换SDK版本、重新下载LWJGL库、修改源代码,均未解决问题。
报错信息
Hello LWJGL 3.3.1 build 7! [LWJGL] [ThreadLocalUtil] Unsupported JNI version detected, this may result in a crash. Please inform LWJGL developers. # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffc3c5aba56, pid=6740, tid=14624 # # JRE version: Java(TM) SE Runtime Environment (19.0.1+10) (build 19.0.1+10-21) # Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0.1+10-21, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64) # Problematic frame: # C [ntdll.dll+0x3ba56] # # No core dump will be written. Minidumps are not enabled by default on client versions of Windows # # An error report file with more information is saved as: # D:\\IntelliJ IDEA Projects\\Game Project\\hs_err_pid6740.log # # If you would like to submit a bug report, please visit: # https://bugreport.java.com/bugreport/crash.jsp # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. # Process finished with exit code 1
源代码
import org.lwjgl.*; import org.lwjgl.glfw.*; import org.lwjgl.opengl.*; import org.lwjgl.system.*; import java.nio.*; import java.util.Objects; import static org.lwjgl.glfw.Callbacks.*; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.system.MemoryStack.*; import static org.lwjgl.system.MemoryUtil.*; public class main { private long window; public void run() { System.out.println("Hello LWJGL " + Version.getVersion() + "!"); init(); loop(); glfwFreeCallbacks(window); glfwDestroyWindow(window); glfwTerminate(); Objects.requireNonNull(glfwSetErrorCallback(null)).free(); } private void init() { GLFWErrorCallback.createPrint(System.err).set(); if ( !glfwInit() ) { throw new IllegalStateException("Unable to initialize GLFW"); } glfwDefaultWindowHints(); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); int windowWidth = 640; int windowHeight = 480; window = glfwCreateWindow(windowWidth, windowHeight, "Game", GLFW_RESIZABLE, NULL); if ( window == NULL ) throw new RuntimeException("Failed to create the GLFW window"); glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> { if ( key == GLFW_KEY_ESCAPE && action == GLFW_PRESS ) glfwSetWindowShouldClose(window, true); }); try ( MemoryStack stack = stackPush() ) { IntBuffer pWidth = stack.mallocInt(1); // int* IntBuffer pHeight = stack.mallocInt(1); // int* glfwGetWindowSize(window, pWidth, pHeight); GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); assert vidmode != null; glfwSetWindowPos( window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2 ); } glfwMakeContextCurrent(window); glfwSwapInterval(1); glfwShowWindow(window); } private void loop() { GL.createCapabilities(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); while ( !glfwWindowShouldClose(window) ) { glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_POLYGON); glEnd(); glfwSwapBuffers(window); glfwPollEvents(); } } public static void main(String[] args) { new main().run(); } }
崩溃问题解决方案
- 修正窗口创建参数错误:源代码中
glfwCreateWindow的第四个参数错误传入了GLFW_RESIZABLE,该参数应为共享上下文窗口句柄(通常传NULL),修正后:
这个错误是导致崩溃的核心诱因之一。window = glfwCreateWindow(windowWidth, windowHeight, "Game", NULL, NULL); - 匹配LWJGL与JDK版本:LWJGL 3.3.1对JDK 19的兼容性不佳,建议降级至JDK 11或17(LTS版本),LWJGL对长期支持版本的JDK适配更稳定。
- 添加JVM启动参数:在IDEA的运行配置中添加以下参数,规避JNI版本检测问题:
-XX:+DisableAttachMechanism -Dorg.lwjgl.system.ThreadLocalUtil.allocator=system - 校验native库完整性:重新生成LWJGL依赖包,确保勾选GLFW、OpenGL模块,且native库对应Windows x64平台,替换项目中现有库文件。
- 安装VC++运行库:确保系统安装了最新的Visual C++ Redistributable运行库,LWJGL的native依赖需要该环境支持。
代码优化建议
- 类名规范化:Java类名遵循大驼峰命名,将
main改为GameMain。 - 安全释放资源:将资源释放逻辑放入
finally块,避免异常时资源泄漏:public void run() { System.out.println("Hello LWJGL " + Version.getVersion() + "!"); try { init(); loop(); } finally { glfwFreeCallbacks(window); glfwDestroyWindow(window); glfwTerminate(); GLFWErrorCallback errorCallback = glfwSetErrorCallback(null); if (errorCallback != null) { errorCallback.free(); } } } - 移除无效代码:
loop方法中glBegin(GL_POLYGON); glEnd();未绘制任何顶点,属于无效代码,直接删除。 - 替换断言为显式检查:断言在生产环境可能被禁用,替换为异常抛出:
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); if (vidmode == null) { throw new IllegalStateException("Failed to retrieve primary monitor video mode"); } - 优化窗口位置计算:直接在创建窗口时指定居中,避免额外的
glfwGetWindowSize调用:try (MemoryStack stack = stackPush()) { GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); if (vidmode == null) { throw new IllegalStateException("Failed to retrieve primary monitor video mode"); } window = glfwCreateWindow(windowWidth, windowHeight, "Game", NULL, NULL); if (window == NULL) { throw new RuntimeException("Failed to create the GLFW window"); } glfwSetWindowPos( window, (vidmode.width() - windowWidth) / 2, (vidmode.height() - windowHeight) / 2 ); }
内容的提问来源于stack exchange,提问作者Foryxled_Dev
相关产品推荐
相关产品推荐

