Skip to content

Commit 9532659

Browse files
committed
fix: Skip JNI native access check on JDK < 24 (fixes #1689)
Module.isNativeAccessEnabled() was backported to some JDK 21 builds (e.g. 21.0.10), causing a false UnsupportedOperationException since the method returns false even though JNI works without --enable-native-access. JNI native access restrictions are only enforced from JDK 24+, so skip the check on earlier versions.
1 parent 4e7d7e1 commit 9532659

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

terminal-jni/src/main/java/org/jline/terminal/impl/jni/JniTerminalProvider.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ public JniTerminalProvider() {
7070

7171
/**
7272
* Checks that native access is enabled for this module.
73-
* Uses reflection because {@code Module.isNativeAccessEnabled()} is only available on JDK 22+
74-
* (though GraalVM backported it to earlier versions).
75-
* On JDKs without this method, the check is skipped (no restrictions exist).
73+
* JNI native access restrictions are only enforced from JDK 24+, so the check
74+
* is skipped on earlier versions. Uses reflection because
75+
* {@code Module.isNativeAccessEnabled()} is not available on all JDK versions.
7676
* In GraalVM native images, the check is also skipped since native libraries
7777
* are handled at build time.
7878
*
@@ -84,6 +84,13 @@ static void checkNativeAccess() {
8484
if (System.getProperty("org.graalvm.nativeimage.imagecode") != null) {
8585
return;
8686
}
87+
// JNI native access restrictions are only enforced starting from JDK 24.
88+
// Some JDK 21 builds (e.g. 21.0.10) backported Module.isNativeAccessEnabled(),
89+
// but it returns false even though JNI works fine without --enable-native-access.
90+
// See https://github.com/jline/jline3/issues/1689
91+
if (Runtime.version().feature() < 24) {
92+
return;
93+
}
8794
try {
8895
Method m = Module.class.getMethod("isNativeAccessEnabled");
8996
Boolean enabled = (Boolean) m.invoke(JniTerminalProvider.class.getModule());
@@ -92,7 +99,7 @@ static void checkNativeAccess() {
9299
+ JniTerminalProvider.class.getModule());
93100
}
94101
} catch (NoSuchMethodException e) {
95-
// JDK < 22, no native access restrictions
102+
// Method not available, no native access restrictions
96103
} catch (UnsupportedOperationException e) {
97104
throw e;
98105
} catch (ReflectiveOperationException e) {

terminal/src/main/java/org/jline/terminal/impl/exec/ExecTerminalProvider.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,12 +623,20 @@ public ProcessBuilder.Redirect newRedirectPipe(FileDescriptor fd) {
623623

624624
/**
625625
* Checks that native access is enabled for this module.
626-
* Uses reflection because {@code Module.isNativeAccessEnabled()} is only available on JDK 22+.
627-
* On older JDKs, the check is skipped (no restrictions exist).
626+
* JNI native access restrictions are only enforced from JDK 24+, so the check
627+
* is skipped on earlier versions. Uses reflection because
628+
* {@code Module.isNativeAccessEnabled()} is not available on all JDK versions.
628629
*
629630
* @throws UnsupportedOperationException if native access is not enabled
630631
*/
631632
static void checkNativeAccess() {
633+
// JNI native access restrictions are only enforced starting from JDK 24.
634+
// Some JDK 21 builds (e.g. 21.0.10) backported Module.isNativeAccessEnabled(),
635+
// but it returns false even though JNI works fine without --enable-native-access.
636+
// See https://github.com/jline/jline3/issues/1689
637+
if (Runtime.version().feature() < 24) {
638+
return;
639+
}
632640
try {
633641
Method m = Module.class.getMethod("isNativeAccessEnabled");
634642
Boolean enabled = (Boolean) m.invoke(ExecTerminalProvider.class.getModule());
@@ -637,7 +645,7 @@ static void checkNativeAccess() {
637645
+ ExecTerminalProvider.class.getModule());
638646
}
639647
} catch (NoSuchMethodException e) {
640-
// JDK < 22, no native access restrictions
648+
// Method not available, no native access restrictions
641649
} catch (UnsupportedOperationException e) {
642650
throw e;
643651
} catch (ReflectiveOperationException e) {

0 commit comments

Comments
 (0)