Skip to content

Commit f9b2461

Browse files
committed
[GR-54648] Require that built-in libraries must have a JNI_OnLoad_libname function.
PullRequest: graal/18239
2 parents a94f859 + 8e92fec commit f9b2461

File tree

3 files changed

+25
-34
lines changed

3 files changed

+25
-34
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNILibraryInitializer.java

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,14 @@ public class JNILibraryInitializer implements NativeLibrarySupport.LibraryInitia
5656

5757
private final EconomicMap<String, CGlobalData<PointerBase>> onLoadCGlobalDataMap = ImageHeapMap.create(Equivalence.IDENTITY);
5858

59-
public static String getOnLoadName(String libName, boolean isBuiltIn) {
59+
private static String getOnLoadName(String libName, boolean isBuiltIn) {
6060
String name = "JNI_OnLoad";
6161
if (isBuiltIn) {
6262
return name + "_" + libName;
6363
}
6464
return name;
6565
}
6666

67-
private static void callOnLoadFunction(String libName, PointerBase onLoadFunction) {
68-
if (onLoadFunction.isNonNull()) {
69-
JNIOnLoadFunctionPointer onLoad = (JNIOnLoadFunctionPointer) onLoadFunction;
70-
int expected = onLoad.invoke(JNIFunctionTables.singleton().getGlobalJavaVM(), WordFactory.nullPointer());
71-
checkSupportedJNIVersion(libName, expected);
72-
}
73-
}
74-
75-
private static void checkSupportedJNIVersion(String libName, int expected) {
76-
if (!JNIVersion.isSupported(expected)) {
77-
String message = "Unsupported JNI version 0x" + Integer.toHexString(expected) + ", required by " + libName;
78-
throw new UnsatisfiedLinkError(message);
79-
}
80-
}
81-
8267
public boolean fillCGlobalDataMap(Collection<String> staticLibNames) {
8368
List<String> libsWithOnLoad = Arrays.asList("net", "java", "nio", "zip", "sunec", "jaas", "sctp", "extnet",
8469
"j2gss", "j2pkcs11", "j2pcsc", "prefs", "verify", "awt", "awt_xawt", "awt_headless", "lcms",
@@ -118,17 +103,23 @@ public void initialize(PlatformNativeLibrarySupport.NativeLibrary lib) {
118103
if (lib.isBuiltin()) {
119104
onLoadFunction = getOnLoadSymbolAddress(libName);
120105
if (onLoadFunction.isNull()) {
121-
/*
122-
* If pointer for static library not found, try to initialize library as shared
123-
*/
124106
String symbolName = getOnLoadName(libName, true);
125107
onLoadFunction = lib.findSymbol(symbolName);
108+
if (onLoadFunction.isNull()) {
109+
throw new UnsatisfiedLinkError("Missing mandatory function for statically linked JNI library: " + symbolName);
110+
}
126111
}
127112
} else {
128113
String symbolName = getOnLoadName(libName, false);
129114
onLoadFunction = lib.findSymbol(symbolName);
130115
}
131-
callOnLoadFunction(libName, onLoadFunction);
116+
if (onLoadFunction.isNonNull()) {
117+
JNIOnLoadFunctionPointer onLoad = (JNIOnLoadFunctionPointer) onLoadFunction;
118+
int expected = onLoad.invoke(JNIFunctionTables.singleton().getGlobalJavaVM(), WordFactory.nullPointer());
119+
if (!JNIVersion.isSupported(expected, lib.isBuiltin())) {
120+
throw new UnsatisfiedLinkError("Unsupported JNI version 0x" + Integer.toHexString(expected) + ", required by " + libName);
121+
}
122+
}
132123
}
133124

134125
private PointerBase getOnLoadSymbolAddress(String libName) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIInvocationInterface.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static int JNI_CreateJavaVM(@SuppressWarnings("unused") JNIJavaVMPointer vmBuf,
235235
@Uninterruptible(reason = "No Java context")
236236
static int JNI_GetDefaultJavaVMInitArgs(JNIJavaVMInitArgs vmArgs) {
237237
int version = vmArgs.getVersion();
238-
if (JNIVersion.isSupported(vmArgs.getVersion()) && version != JNIVersion.JNI_VERSION_1_1()) {
238+
if (JNIVersion.isSupported(vmArgs.getVersion(), false) && version != JNIVersion.JNI_VERSION_1_1()) {
239239
return JNIErrors.JNI_OK();
240240
}
241241
if (version == JNIVersion.JNI_VERSION_1_1()) {
@@ -324,7 +324,7 @@ static int enter(JNIJavaVM vm, WordPointer env, int version) {
324324
if (vm.isNull() || env.isNull()) {
325325
return JNIErrors.JNI_ERR();
326326
}
327-
if (!JNIVersion.isSupported(version)) {
327+
if (!JNIVersion.isSupported(version, false)) {
328328
env.write(WordFactory.nullPointer());
329329
return JNIErrors.JNI_EVERSION();
330330
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@
3434
@CContext(JNIHeaderDirectives.class)
3535
public final class JNIVersion {
3636
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
37-
public static boolean isSupported(int version) {
38-
return (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDKLatest.JNI_VERSION_LATEST()) ||
39-
version == JNI_VERSION_21() ||
40-
version == JNI_VERSION_20() ||
41-
version == JNI_VERSION_19() ||
42-
version == JNI_VERSION_10() ||
43-
version == JNI_VERSION_9() ||
44-
version == JNI_VERSION_1_8() ||
45-
version == JNI_VERSION_1_6() ||
46-
version == JNI_VERSION_1_4() ||
47-
version == JNI_VERSION_1_2() ||
48-
version == JNI_VERSION_1_1();
37+
public static boolean isSupported(int version, boolean builtInLibrary) {
38+
if (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDKLatest.JNI_VERSION_LATEST()) {
39+
return true;
40+
}
41+
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()) {
42+
return true;
43+
}
44+
if (builtInLibrary) {
45+
// Specification requires 1.8 or later for built-in (statically linked) libraries.
46+
return false;
47+
}
48+
return version == JNI_VERSION_1_6() || version == JNI_VERSION_1_4() || version == JNI_VERSION_1_2() || version == JNI_VERSION_1_1();
4949
}
5050

5151
// Checkstyle: stop

0 commit comments

Comments
 (0)