diff --git a/core/src/main/java/org/jruby/ext/ffi/Platform.java b/core/src/main/java/org/jruby/ext/ffi/Platform.java index a07c0575737..7a2ab25fa48 100644 --- a/core/src/main/java/org/jruby/ext/ffi/Platform.java +++ b/core/src/main/java/org/jruby/ext/ffi/Platform.java @@ -63,7 +63,6 @@ public class Platform { protected final int addressSize, longSize; private final long addressMask; protected final Pattern libPattern; - private int javaVersionMajor = -1; public enum OS_TYPE { DARWIN, @@ -276,34 +275,9 @@ public final CPU_TYPE getCPU() { return CPU; } - /** - * Gets the version of the Java Virtual Machine (JVM) jffi is running on. - * - * @return A number representing the java version. e.g. 8 for java 1.8, 9 for java 9 - */ + @Deprecated public final int getJavaMajorVersion() { - if (javaVersionMajor != -1) return javaVersionMajor; - - int version = 5; - try { - String versionString = SafePropertyAccessor.getProperty("java.version"); - if (versionString != null) { - // remove additional version identifiers, e.g. -ea - versionString = versionString.split("-|\\+")[0]; - String[] v = versionString.split("\\."); - if (v[0].equals("1")) { - // Pre Java 9, 1.x style - version = Integer.valueOf(v[1]); - } else { - // Java 9+, x.y.z style - version = Integer.valueOf(v[0]); - } - } - } catch (Exception ex) { - version = 0; - } - - return javaVersionMajor = version; + return org.jruby.platform.Platform.JAVA_VERSION; } public final boolean isBSD() { return OS == OS.FREEBSD || OS == OS.OPENBSD || OS == OS.NETBSD || OS == OS.DARWIN || OS == OS.DRAGONFLYBSD; diff --git a/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java b/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java index 7518ca151ac..b538173366d 100644 --- a/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java +++ b/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java @@ -8,6 +8,7 @@ import org.jruby.java.util.ClassUtils; import org.jruby.javasupport.Java; import org.jruby.javasupport.JavaSupportImpl; +import org.jruby.platform.Platform; import org.jruby.runtime.Block; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; @@ -717,17 +718,28 @@ private static class PartitionedMethods { } private static boolean filterAccessible(Method method, int mod) { - // Skip private methods, since they may mess with dispatch - if (Modifier.isPrivate(mod)) return false; - - // Skip protected methods if we can't set accessible - if (!Modifier.isPublic(mod) && !Java.trySetAccessible(method)) return false; - - // ignore bridge methods because we'd rather directly call methods that this method - // is bridging (and such methods are by definition always available.) + // Exclude bridge methods if ((mod & ACC_BRIDGE) != 0) return false; - return true; + if (Modifier.isPublic(mod)) { + // Include public + return true; + } else if (Modifier.isPrivate(mod)) { + // Exclude private + return false; + } else if (Modifier.isProtected(mod)) { + // Include protected if they can be set accessible + return Java.trySetAccessible(method); + } else { + // We split this on 17 because at that level unopened non-public functions are inaccessible + if (Platform.JAVA_VERSION < 17) { + // Include package-private if they can be set accessible on Java 16 and earlier + return Java.trySetAccessible(method); + } else { + // Exclude package-private on Java 17 and later + return false; + } + } } } } diff --git a/core/src/main/java/org/jruby/platform/Platform.java b/core/src/main/java/org/jruby/platform/Platform.java index 300ad084ac0..c52ba467654 100644 --- a/core/src/main/java/org/jruby/platform/Platform.java +++ b/core/src/main/java/org/jruby/platform/Platform.java @@ -94,10 +94,41 @@ private static String initArchitecture() { return arch; } + + /** + * Gets the version of the Java platform that JRuby is running on. + */ + private static int initJavaVersion() { + int version = 5; + try { + String versionString = SafePropertyAccessor.getProperty("java.version"); + if (versionString != null) { + // remove additional version identifiers, e.g. -ea + versionString = versionString.split("-|\\+")[0]; + String[] v = versionString.split("\\."); + if (v[0].equals("1")) { + // Pre Java 9, 1.x style + version = Integer.valueOf(v[1]); + } else { + // Java 9+, x.y.z style + version = Integer.valueOf(v[0]); + } + } + } catch (Exception ex) { + version = 0; + } + + return version; + } + public static final String ARCH = initArchitecture(); public static final String OS = initOperatingSystem(); public static final String JVM = getProperty("java.vm.name", "unknown"); public static final String OS_VERSION = getProperty("os.version", "unknown"); + /** + * An integer value representing the major Java/JDK release, e.g. 8 for java 1.8, 9 for java 9. + */ + public static final int JAVA_VERSION = initJavaVersion(); public static final boolean IS_WINDOWS = OS.equals(WINDOWS);