Skip to content

Commit 98e3194

Browse files
committed
replace LibGraalLoader.getJavaHome with a protocol shared between HostedLibGraalClassLoader and LibGraalFeature
1 parent 81f7c8e commit 98e3194

File tree

4 files changed

+54
-25
lines changed

4 files changed

+54
-25
lines changed

compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@
6161

6262
/**
6363
* A classloader that reads class files and resources from a jimage file and a module path at image
64-
* build time.
64+
* build time. The {@code java.home} of the JDK containing the jimage can be obtained by converting
65+
* the bytes of {@code getResourceAsStream("META-INF/libgraal.java.home")} to a string.
6566
*/
6667
@Platforms(Platform.HOSTED_ONLY.class)
6768
public final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalLoader {
@@ -72,6 +73,12 @@ public final class HostedLibGraalClassLoader extends ClassLoader implements LibG
7273
*/
7374
private static final String LIBGRAAL_JAVA_HOME_PROPERTY_NAME = "libgraal.java.home";
7475

76+
/**
77+
* The {@code java.home} of the JDK whose runtime image contains the Graal and JVMCI classes
78+
* from which libgraal will be built.
79+
*/
80+
private static final Path LIBGRAAL_JAVA_HOME = Path.of(System.getProperty(LIBGRAAL_JAVA_HOME_PROPERTY_NAME, System.getProperty("java.home")));
81+
7582
/**
7683
* Name of the system property specifying a module path for the module(s) containing
7784
* {@code LibGraalFeature} and its dependencies that are not available in the runtime image.
@@ -177,13 +184,6 @@ byte[] readBytes() throws ClassNotFoundException {
177184
ClassLoader.registerAsParallelCapable();
178185
}
179186

180-
private final Path libgraalJavaHome = Path.of(System.getProperty(LIBGRAAL_JAVA_HOME_PROPERTY_NAME, System.getProperty("java.home")));
181-
182-
@Override
183-
public Path getJavaHome() {
184-
return libgraalJavaHome;
185-
}
186-
187187
/**
188188
* Converts the module path entry {@code s} to a {@link Path}.
189189
*
@@ -219,7 +219,7 @@ public HostedLibGraalClassLoader() {
219219

220220
Map<String, String> modulesMap = new HashMap<>();
221221

222-
Path imagePath = libgraalJavaHome.resolve(Path.of("lib", "modules"));
222+
Path imagePath = LIBGRAAL_JAVA_HOME.resolve(Path.of("lib", "modules"));
223223
this.imageReader = BasicImageReader.open(imagePath);
224224
for (var entry : imageReader.getEntryNames()) {
225225
int secondSlash = entry.indexOf('/', 1);
@@ -316,6 +316,12 @@ protected Class<?> findClass(final String name) throws ClassNotFoundException {
316316
*/
317317
private static final String SERVICE_PROTOCOL = "service-config";
318318

319+
/**
320+
* Name of the protocol for accessing a file whose contents are the {@code java.home} of the JDK
321+
* whose runtime image contains the Graal and JVMCI * classes from which libgraal will be built.
322+
*/
323+
private static final String LIBGRAAL_JAVA_HOME_PROTOCOL = "libgraal-java-home";
324+
319325
/**
320326
* Name of the protocol for accessing entries in {@link #resources}.
321327
*/
@@ -329,7 +335,14 @@ protected URL findResource(String name) {
329335
if (handler == null) {
330336
this.serviceHandler = handler = new ImageURLStreamHandler();
331337
}
332-
if (name.startsWith("META-INF/services/")) {
338+
if (name.equals("META-INF/libgraal.java.home")) {
339+
try {
340+
var uri = new URI(LIBGRAAL_JAVA_HOME_PROTOCOL, "libgraal.java.home", null);
341+
return URL.of(uri, handler);
342+
} catch (URISyntaxException | MalformedURLException e) {
343+
return null;
344+
}
345+
} else if (name.startsWith("META-INF/services/")) {
333346
String service = name.substring("META-INF/services/".length());
334347
if (services.containsKey(service)) {
335348
try {
@@ -370,7 +383,12 @@ private class ImageURLStreamHandler extends URLStreamHandler {
370383
@Override
371384
public URLConnection openConnection(URL u) {
372385
String protocol = u.getProtocol();
373-
if (protocol.equalsIgnoreCase(SERVICE_PROTOCOL)) {
386+
if (protocol.equalsIgnoreCase(LIBGRAAL_JAVA_HOME_PROTOCOL)) {
387+
if (!u.getPath().equals("libgraal.java.home")) {
388+
throw new IllegalArgumentException(u.toString());
389+
}
390+
return new ImageURLConnection(u, LIBGRAAL_JAVA_HOME.toString().getBytes());
391+
} else if (protocol.equalsIgnoreCase(SERVICE_PROTOCOL)) {
374392
List<String> providers = services.get(u.getPath());
375393
if (providers != null) {
376394
return new ImageURLConnection(u, String.join("\n", providers).getBytes());

compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/GetJNIConfig.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import jdk.graal.compiler.serviceprovider.GraalServices;
4444
import jdk.graal.compiler.util.SignatureUtil;
45+
import jdk.graal.nativeimage.LibGraalLoader;
4546
import org.graalvm.nativeimage.Platform;
4647
import org.graalvm.nativeimage.Platforms;
4748
import org.graalvm.nativeimage.hosted.RuntimeJNIAccess;
@@ -78,9 +79,9 @@ final class GetJNIConfig implements AutoCloseable {
7879

7980
int lineNo;
8081

81-
private GetJNIConfig(ClassLoader loader) {
82+
private GetJNIConfig(ClassLoader loader, Path libgraalJavaHome) {
8283
this.loader = loader;
83-
Path javaExe = getJavaExe(Path.of(GraalServices.getSavedProperty("java.home")));
84+
Path javaExe = getJavaExe(libgraalJavaHome);
8485
configFilePath = Path.of("libgraal_jniconfig.txt");
8586

8687
String[] command = {javaExe.toFile().getAbsolutePath(), "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:JVMCILibDumpJNIConfig=" + configFilePath};
@@ -196,8 +197,8 @@ private GraalError error(String format, Object... args) {
196197
* @param loader used to resolve type names in the config
197198
*/
198199
@SuppressWarnings("try")
199-
public static void register(ClassLoader loader) {
200-
try (GetJNIConfig source = new GetJNIConfig(loader)) {
200+
public static void register(ClassLoader loader, Path libgraalJavaHome) {
201+
try (GetJNIConfig source = new GetJNIConfig(loader, libgraalJavaHome)) {
201202
Map<String, Class<?>> classes = new HashMap<>();
202203
for (String line : source.lines) {
203204
source.lineNo++;

compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/LibGraalFeature.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
package jdk.graal.compiler.libgraal;
2626

27+
import java.io.IOException;
28+
import java.io.InputStream;
2729
import java.lang.module.ModuleDescriptor;
2830
import java.lang.reflect.Field;
2931
import java.lang.reflect.Modifier;
@@ -114,7 +116,23 @@ public boolean getAsBoolean() {
114116
}
115117
}
116118

119+
/**
120+
* See javadoc for {@code jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader}.
121+
*/
122+
private static Path readLibgraalJavaHome(ClassLoader cl) {
123+
try (InputStream in = cl.getResourceAsStream("META-INF/libgraal.java.home")) {
124+
if (in == null) {
125+
throw new GraalError(cl.getClass().getName() + " does not support META-INF/libgraal.java.home protocol (see javadoc of HostedLibGraalClassLoader)");
126+
}
127+
return Path.of(new String(in.readAllBytes()));
128+
} catch (IOException e) {
129+
throw new GraalError(e);
130+
}
131+
}
132+
117133
private final LibGraalLoader libgraalLoader = (LibGraalLoader) getClass().getClassLoader();
134+
private final Path libgraalJavaHome = readLibgraalJavaHome(getClass().getClassLoader());
135+
118136
private BeforeAnalysisAccess beforeAnalysisAccess;
119137
private BeforeCompilationAccess beforeCompilationAccess;
120138
private OptionCollector optionCollector;
@@ -158,7 +176,7 @@ public void duringSetup(DuringSetupAccess access) {
158176
beforeAnalysisAccess.registerAsUnsafeAllocated(clazz);
159177
}
160178
}, NodeClass.class);
161-
GetJNIConfig.register((ClassLoader) libgraalLoader);
179+
GetJNIConfig.register((ClassLoader) libgraalLoader, libgraalJavaHome);
162180
}
163181

164182
/**
@@ -275,8 +293,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
275293

276294
doLegacyJVMCIInitialization();
277295

278-
Path libGraalJavaHome = libgraalLoader.getJavaHome();
279-
GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome);
296+
GetCompilerConfig.Result configResult = GetCompilerConfig.from(libgraalJavaHome);
280297
for (var e : configResult.opens().entrySet()) {
281298
Module module = ModuleLayer.boot().findModule(e.getKey()).orElseThrow();
282299
for (String source : e.getValue()) {

sdk/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
*/
4141
package jdk.graal.nativeimage;
4242

43-
import java.nio.file.Path;
4443
import java.util.Map;
4544

4645
/**
@@ -51,12 +50,6 @@
5150
*/
5251
public interface LibGraalLoader {
5352

54-
/**
55-
* Gets the {@code java.home} of the JDK whose runtime image contains the Graal and JVMCI
56-
* classes from which libgraal will be built.
57-
*/
58-
Path getJavaHome();
59-
6053
/**
6154
* Gets a map from the {@linkplain Class#forName(String) name} of a class to the name of its
6255
* enclosing module. There is one entry in the map for each class available for loading by this

0 commit comments

Comments
 (0)