fix(lwjgl): Load pojavexec earlier

Fixes 26.2-snapshot-4 crash

We put System.loadLibrary("pojavexec") in Library.java and Sys.java and
seperate out GLFW pojavexec init to GLFW static block initializer.

Uses
(3.4.1)
b84bec48c8
https://github.com/AngelAuraMC/lwjgl3/actions/runs/24783965974
(3.3.3)
b0ee05e894
https://github.com/AngelAuraMC/lwjgl3/actions/runs/24783304994
This commit is contained in:
tomikun
2026-04-22 01:07:01 +08:00
parent a876e9e858
commit dd94a7f2e8
56 changed files with 39 additions and 14 deletions

View File

@@ -1 +1 @@
d562b83d28c54d14bbb2f0366ed428945100310e
7e958ece157c2208c2a8c715a4f92b684b112cfa

View File

@@ -1 +1 @@
3999dc44bce7e9d269e034e79c7e430f88a50f3e
80680c59be7562f6efefb301122e421068d6c652

View File

@@ -862,9 +862,13 @@ public final class Tools {
String internalLwjglVersion = iLwjglVersion >= 341 ? "3.4.1" : "3.3.3";
File lwjgl3Folder = new File(Tools.DIR_GAME_HOME, "lwjgl3/"+internalLwjglVersion);
String lwjglCore = lwjgl3Folder.getAbsolutePath() + "/lwjgl.jar";
String lwjglMerged = lwjgl3Folder.getAbsolutePath() + "/lwjgl-"+internalLwjglVersion+"-merged-modules";
String lwjglxFile = lwjgl3Folder + "/lwjgl-lwjglx.jar";
launchClasspath.append(lwjglCore).append(":");
// 2nd in priority in case we need to merge lwjgl.jar again for testing
launchClasspath.append(lwjglMerged).append(":");
File[] lwjglModules = lwjgl3Folder.listFiles(pathname ->
pathname.getName().endsWith(".jar") &&

View File

@@ -48,6 +48,10 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
LOGI("Saving DVM environ...");
//Save dalvik global JavaVM pointer
pojav_environ->dalvikJavaVMPtr = vm;
// Sets up the stuff that GLFW/JVM needs to communicate to Android
// These methods are called from GLFW/JVM and connect to Android-side impls
// These aren't separated out into a method because these can be ran so long as we are in Android-land
// so that means this library must be loaded at least once in Android-land
JNIEnv *dvEnv;
(*vm)->GetEnv(vm, (void**) &dvEnv, JNI_VERSION_1_4);
pojav_environ->bridgeClazz = (*dvEnv)->NewGlobalRef(dvEnv,(*dvEnv) ->FindClass(dvEnv,"org/lwjgl/glfw/CallbackBridge"));
@@ -60,17 +64,7 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
LOGI("Saving JVM environ...");
pojav_environ->runtimeJavaVMPtr = vm;
JNIEnv *vmEnv;
(*vm)->GetEnv(vm, (void**) &vmEnv, JNI_VERSION_1_4);
pojav_environ->vmGlfwClass = (*vmEnv)->NewGlobalRef(vmEnv, (*vmEnv)->FindClass(vmEnv, "org/lwjgl/glfw/GLFW"));
pojav_environ->method_glftSetWindowAttrib = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "glfwSetWindowAttrib", "(JII)V");
pojav_environ->method_internalWindowSizeChanged = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "internalWindowSizeChanged", "(J)V");
pojav_environ->method_internalChangeMonitorSize = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "internalChangeMonitorSize", "(II)V");
jfieldID field_keyDownBuffer = (*vmEnv)->GetStaticFieldID(vmEnv, pojav_environ->vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;");
jobject keyDownBufferJ = (*vmEnv)->GetStaticObjectField(vmEnv, pojav_environ->vmGlfwClass, field_keyDownBuffer);
pojav_environ->keyDownBuffer = (*vmEnv)->GetDirectBufferAddress(vmEnv, keyDownBufferJ);
jfieldID field_mouseDownBuffer = (*vmEnv)->GetStaticFieldID(vmEnv, pojav_environ->vmGlfwClass, "mouseDownBuffer", "Ljava/nio/ByteBuffer;");
jobject mouseDownBufferJ = (*vmEnv)->GetStaticObjectField(vmEnv, pojav_environ->vmGlfwClass, field_mouseDownBuffer);
pojav_environ->mouseDownBuffer = (*vmEnv)->GetDirectBufferAddress(vmEnv, mouseDownBufferJ);
(*pojav_environ->runtimeJavaVMPtr)->GetEnv(pojav_environ->runtimeJavaVMPtr, (void**) &vmEnv, JNI_VERSION_1_4);
hookExec(vmEnv);
installLwjglDlopenHook(vmEnv);
installEMUIIteratorMititgation(vmEnv);
@@ -87,6 +81,26 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
return JNI_VERSION_1_4;
}
// Sets up the stuff that Android needs to communicate to GLFW/JVM
// These methods are called from Android and connect to GLFW/JVM-side impls
// These are separated out into a method because GLFW loads much later than when we need to dlopen
// pojavexec since it does more than just GLFW.
// TODO: Add checks in case someone forgets to run this method. Probably see if pojav_environ->vmGlfwClass is null or not
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nativeInitializeGLFWNativeBridge(__attribute__((unused)) JNIEnv* env, __attribute__((unused)) jclass clazz) {
JNIEnv *vmEnv;
(*pojav_environ->runtimeJavaVMPtr)->GetEnv(pojav_environ->runtimeJavaVMPtr, (void**) &vmEnv, JNI_VERSION_1_4);
pojav_environ->vmGlfwClass = (*vmEnv)->NewGlobalRef(vmEnv, (*vmEnv)->FindClass(vmEnv, "org/lwjgl/glfw/GLFW"));
pojav_environ->method_glftSetWindowAttrib = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "glfwSetWindowAttrib", "(JII)V");
pojav_environ->method_internalWindowSizeChanged = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "internalWindowSizeChanged", "(J)V");
pojav_environ->method_internalChangeMonitorSize = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "internalChangeMonitorSize", "(II)V");
jfieldID field_keyDownBuffer = (*vmEnv)->GetStaticFieldID(vmEnv, pojav_environ->vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;");
jobject keyDownBufferJ = (*vmEnv)->GetStaticObjectField(vmEnv, pojav_environ->vmGlfwClass, field_keyDownBuffer);
pojav_environ->keyDownBuffer = (*vmEnv)->GetDirectBufferAddress(vmEnv, keyDownBufferJ);
jfieldID field_mouseDownBuffer = (*vmEnv)->GetStaticFieldID(vmEnv, pojav_environ->vmGlfwClass, "mouseDownBuffer", "Ljava/nio/ByteBuffer;");
jobject mouseDownBufferJ = (*vmEnv)->GetStaticObjectField(vmEnv, pojav_environ->vmGlfwClass, field_mouseDownBuffer);
pojav_environ->mouseDownBuffer = (*vmEnv)->GetDirectBufferAddress(vmEnv, mouseDownBufferJ);
}
#define ADD_CALLBACK_WWIN(NAME) \
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSet##NAME##Callback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) { \
void** oldCallback = (void**) &pojav_environ->GLFW_invoke_##NAME; \

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -522,10 +522,13 @@ public class GLFW
private static final String PROP_WINDOW_HEIGHT= "glfwstub.windowHeight";
public static long mainContext = 0;
private static long gamepadDataPointer;
private static native void nativeInitializeGLFWNativeBridge();
static {
try {
// Mods like LWJGL3ify have more of a chance of overriding the other classes so
// lets just load it here again just to be safe.
System.loadLibrary("pojavexec");
nativeInitializeGLFWNativeBridge();
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
}

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -529,9 +529,13 @@ public class GLFW
public static long mainContext = 0;
private static long gamepadDataPointer;
private static native void nativeInitializeGLFWNativeBridge();
static {
try {
// Mods like LWJGL3ify have more of a chance of overriding the other classes so
// lets just load it here again just to be safe.
System.loadLibrary("pojavexec");
nativeInitializeGLFWNativeBridge();
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
}