61
61
62
62
/**
63
63
* 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.
65
66
*/
66
67
@ Platforms (Platform .HOSTED_ONLY .class )
67
68
public final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalLoader {
@@ -72,6 +73,12 @@ public final class HostedLibGraalClassLoader extends ClassLoader implements LibG
72
73
*/
73
74
private static final String LIBGRAAL_JAVA_HOME_PROPERTY_NAME = "libgraal.java.home" ;
74
75
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
+
75
82
/**
76
83
* Name of the system property specifying a module path for the module(s) containing
77
84
* {@code LibGraalFeature} and its dependencies that are not available in the runtime image.
@@ -177,13 +184,6 @@ byte[] readBytes() throws ClassNotFoundException {
177
184
ClassLoader .registerAsParallelCapable ();
178
185
}
179
186
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
-
187
187
/**
188
188
* Converts the module path entry {@code s} to a {@link Path}.
189
189
*
@@ -219,7 +219,7 @@ public HostedLibGraalClassLoader() {
219
219
220
220
Map <String , String > modulesMap = new HashMap <>();
221
221
222
- Path imagePath = libgraalJavaHome .resolve (Path .of ("lib" , "modules" ));
222
+ Path imagePath = LIBGRAAL_JAVA_HOME .resolve (Path .of ("lib" , "modules" ));
223
223
this .imageReader = BasicImageReader .open (imagePath );
224
224
for (var entry : imageReader .getEntryNames ()) {
225
225
int secondSlash = entry .indexOf ('/' , 1 );
@@ -316,6 +316,12 @@ protected Class<?> findClass(final String name) throws ClassNotFoundException {
316
316
*/
317
317
private static final String SERVICE_PROTOCOL = "service-config" ;
318
318
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
+
319
325
/**
320
326
* Name of the protocol for accessing entries in {@link #resources}.
321
327
*/
@@ -329,7 +335,14 @@ protected URL findResource(String name) {
329
335
if (handler == null ) {
330
336
this .serviceHandler = handler = new ImageURLStreamHandler ();
331
337
}
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/" )) {
333
346
String service = name .substring ("META-INF/services/" .length ());
334
347
if (services .containsKey (service )) {
335
348
try {
@@ -370,7 +383,12 @@ private class ImageURLStreamHandler extends URLStreamHandler {
370
383
@ Override
371
384
public URLConnection openConnection (URL u ) {
372
385
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 )) {
374
392
List <String > providers = services .get (u .getPath ());
375
393
if (providers != null ) {
376
394
return new ImageURLConnection (u , String .join ("\n " , providers ).getBytes ());
0 commit comments