Apache NetBeans version
Apache NetBeans 29
What happened
JarClassLoader has some Multi-Release logic (lines 622-637). However, there are two fatal flaws in its implementation:
The Constructor Bug: Look at line 568: ret = new JarFile(file, false); It uses the old Java 8 constructor. It does not use the modern new JarFile(file, verify, mode, Runtime.version()). Without that version parameter, the JarFile object itself operates in "Legacy Mode," meaning its internal index doesn't automatically map versioned entries to their base names.
The "New Package" Blind Spot: NetBeans uses a "Covered Packages" index to speed up loading. In listCoveredPackages (line 714), it iterates through the JAR entries. Since the JAR wasn't opened in MR-mode, it sees META-INF/versions/22/org/lwjgl/... as just a random file under META-INF. It does not realize this represents the package org.lwjgl.system.ffm.
The Result: If a package (like ffm) only exists in the versioned folder, NetBeans never adds it to the "Covered Packages" list, and the classloader never even attempts to load it.
Conclusion: Your intuition was 100% correct. NetBeans' MR support is a "half-bridge" that only works for overriding existing classes, but completely fails for the modern "Add-on" packages used by LWJGL.
Language / Project Type / NetBeans Component
NBM maven project
How to reproduce
Try adding LWJGL 3.4.1 as a dependency and then try to initialize the lib with glfwInit(). There is a class there called FFM that is only supposed to be visible for JDK25 because it is in META-INF/versions/25/FMM.class but the JarClassLoader doesn't see it
Did this work correctly in an earlier version?
No / Don't know
Operating System
ubuntu 24
JDK
Temurin 25
Apache NetBeans packaging
Apache NetBeans binary zip, Community provided installer
Anything else
No response
Are you willing to submit a pull request?
No, but the AI generated patch is this:
--- org/netbeans/JarClassLoader.java
+++ org/netbeans/JarClassLoader.java
@@ -565,7 +565,11 @@
long now = System.currentTimeMillis();
JarFile ret;
try {
- ret = new JarFile(file, false);
+ if (RUNTIME_VERSION > BASE_VERSION) {
+ ret = new JarFile(file, false, ZipFile.OPEN_READ, Runtime.version());
+ } else {
+ ret = new JarFile(file, false);
+ }
} catch (FileNotFoundException | NoSuchFileException ex) {
throw (ZipException)new ZipException(ex.getMessage()).initCause(ex);
}
@@ -734,6 +738,15 @@
if (known.add(res)) save.append(res).append(',');
continue;
}
+
+ // MR-JAR Support: Handle versioned entries
+ if (itm.startsWith(META_INF + "versions/")) {
+ int thirdSlash = itm.indexOf('/', META_INF.length() + 9); // Skip META-INF/versions/NN/
+ if (thirdSlash != -1) {
+ itm = itm.substring(thirdSlash + 1);
+ slash = itm.lastIndexOf('/');
+ }
+ }
+
String pkg = slash > 0 ? itm.substring(0, slash).replace('/','.') : "";
if (known.add(pkg)) save.append(pkg).append(',');
}
Apache NetBeans version
Apache NetBeans 29
What happened
JarClassLoader has some Multi-Release logic (lines 622-637). However, there are two fatal flaws in its implementation:
The Constructor Bug: Look at line 568: ret = new JarFile(file, false); It uses the old Java 8 constructor. It does not use the modern new JarFile(file, verify, mode, Runtime.version()). Without that version parameter, the JarFile object itself operates in "Legacy Mode," meaning its internal index doesn't automatically map versioned entries to their base names.
The "New Package" Blind Spot: NetBeans uses a "Covered Packages" index to speed up loading. In listCoveredPackages (line 714), it iterates through the JAR entries. Since the JAR wasn't opened in MR-mode, it sees META-INF/versions/22/org/lwjgl/... as just a random file under META-INF. It does not realize this represents the package org.lwjgl.system.ffm.
The Result: If a package (like ffm) only exists in the versioned folder, NetBeans never adds it to the "Covered Packages" list, and the classloader never even attempts to load it.
Conclusion: Your intuition was 100% correct. NetBeans' MR support is a "half-bridge" that only works for overriding existing classes, but completely fails for the modern "Add-on" packages used by LWJGL.
Language / Project Type / NetBeans Component
NBM maven project
How to reproduce
Try adding LWJGL 3.4.1 as a dependency and then try to initialize the lib with glfwInit(). There is a class there called FFM that is only supposed to be visible for JDK25 because it is in META-INF/versions/25/FMM.class but the JarClassLoader doesn't see it
Did this work correctly in an earlier version?
No / Don't know
Operating System
ubuntu 24
JDK
Temurin 25
Apache NetBeans packaging
Apache NetBeans binary zip, Community provided installer
Anything else
No response
Are you willing to submit a pull request?
No, but the AI generated patch is this: