diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java index f614dc4b3770..c403d1fd55d2 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java @@ -56,7 +56,7 @@ public class JNILibraryInitializer implements NativeLibrarySupport.LibraryInitia private final EconomicMap> onLoadCGlobalDataMap = ImageHeapMap.create(Equivalence.IDENTITY); - public static String getOnLoadName(String libName, boolean isBuiltIn) { + private static String getOnLoadName(String libName, boolean isBuiltIn) { String name = "JNI_OnLoad"; if (isBuiltIn) { return name + "_" + libName; @@ -64,21 +64,6 @@ public static String getOnLoadName(String libName, boolean isBuiltIn) { return name; } - private static void callOnLoadFunction(String libName, PointerBase onLoadFunction) { - if (onLoadFunction.isNonNull()) { - JNIOnLoadFunctionPointer onLoad = (JNIOnLoadFunctionPointer) onLoadFunction; - int expected = onLoad.invoke(JNIFunctionTables.singleton().getGlobalJavaVM(), WordFactory.nullPointer()); - checkSupportedJNIVersion(libName, expected); - } - } - - private static void checkSupportedJNIVersion(String libName, int expected) { - if (!JNIVersion.isSupported(expected)) { - String message = "Unsupported JNI version 0x" + Integer.toHexString(expected) + ", required by " + libName; - throw new UnsatisfiedLinkError(message); - } - } - public boolean fillCGlobalDataMap(Collection staticLibNames) { List libsWithOnLoad = Arrays.asList("net", "java", "nio", "zip", "sunec", "jaas", "sctp", "extnet", "j2gss", "j2pkcs11", "j2pcsc", "prefs", "verify", "awt", "awt_xawt", "awt_headless", "lcms", @@ -118,17 +103,23 @@ public void initialize(PlatformNativeLibrarySupport.NativeLibrary lib) { if (lib.isBuiltin()) { onLoadFunction = getOnLoadSymbolAddress(libName); if (onLoadFunction.isNull()) { - /* - * If pointer for static library not found, try to initialize library as shared - */ String symbolName = getOnLoadName(libName, true); onLoadFunction = lib.findSymbol(symbolName); + if (onLoadFunction.isNull()) { + throw new UnsatisfiedLinkError("Missing mandatory function for statically linked JNI library: " + symbolName); + } } } else { String symbolName = getOnLoadName(libName, false); onLoadFunction = lib.findSymbol(symbolName); } - callOnLoadFunction(libName, onLoadFunction); + if (onLoadFunction.isNonNull()) { + JNIOnLoadFunctionPointer onLoad = (JNIOnLoadFunctionPointer) onLoadFunction; + int expected = onLoad.invoke(JNIFunctionTables.singleton().getGlobalJavaVM(), WordFactory.nullPointer()); + if (!JNIVersion.isSupported(expected, lib.isBuiltin())) { + throw new UnsatisfiedLinkError("Unsupported JNI version 0x" + Integer.toHexString(expected) + ", required by " + libName); + } + } } private PointerBase getOnLoadSymbolAddress(String libName) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIInvocationInterface.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIInvocationInterface.java index 730742e77080..05f94dc3ab1c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIInvocationInterface.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIInvocationInterface.java @@ -231,7 +231,7 @@ static int JNI_CreateJavaVM(@SuppressWarnings("unused") JNIJavaVMPointer vmBuf, @Uninterruptible(reason = "No Java context") static int JNI_GetDefaultJavaVMInitArgs(JNIJavaVMInitArgs vmArgs) { int version = vmArgs.getVersion(); - if (JNIVersion.isSupported(vmArgs.getVersion()) && version != JNIVersion.JNI_VERSION_1_1()) { + if (JNIVersion.isSupported(vmArgs.getVersion(), false) && version != JNIVersion.JNI_VERSION_1_1()) { return JNIErrors.JNI_OK(); } if (version == JNIVersion.JNI_VERSION_1_1()) { @@ -320,7 +320,7 @@ static int enter(JNIJavaVM vm, WordPointer env, int version) { if (vm.isNull() || env.isNull()) { return JNIErrors.JNI_ERR(); } - if (!JNIVersion.isSupported(version)) { + if (!JNIVersion.isSupported(version, false)) { env.write(WordFactory.nullPointer()); return JNIErrors.JNI_EVERSION(); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java index 356a74c4beb2..7204a54f5df6 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java @@ -34,18 +34,18 @@ @CContext(JNIHeaderDirectives.class) public final class JNIVersion { @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public static boolean isSupported(int version) { - return (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDKLatest.JNI_VERSION_LATEST()) || - version == JNI_VERSION_21() || - version == JNI_VERSION_20() || - version == JNI_VERSION_19() || - version == JNI_VERSION_10() || - version == JNI_VERSION_9() || - version == JNI_VERSION_1_8() || - version == JNI_VERSION_1_6() || - version == JNI_VERSION_1_4() || - version == JNI_VERSION_1_2() || - version == JNI_VERSION_1_1(); + public static boolean isSupported(int version, boolean builtInLibrary) { + if (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDKLatest.JNI_VERSION_LATEST()) { + return true; + } + if (version == JNI_VERSION_21() || version == JNI_VERSION_20() || version == JNI_VERSION_19() || version == JNI_VERSION_10() || version == JNI_VERSION_9() || version == JNI_VERSION_1_8()) { + return true; + } + if (builtInLibrary) { + // Specification requires 1.8 or later for built-in (statically linked) libraries. + return false; + } + return version == JNI_VERSION_1_6() || version == JNI_VERSION_1_4() || version == JNI_VERSION_1_2() || version == JNI_VERSION_1_1(); } // Checkstyle: stop