@@ -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 ) {
0 commit comments