57
57
import java .util .Map ;
58
58
import java .util .Optional ;
59
59
import java .util .Set ;
60
- import java .util .stream .Collectors ;
61
60
import java .util .stream .Stream ;
62
61
63
62
/**
64
63
* A classloader that reads class files and resources from a jimage file and a module path at image
65
- * 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.
66
66
*/
67
67
@ Platforms (Platform .HOSTED_ONLY .class )
68
68
public final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalLoader {
@@ -73,6 +73,12 @@ public final class HostedLibGraalClassLoader extends ClassLoader implements LibG
73
73
*/
74
74
private static final String LIBGRAAL_JAVA_HOME_PROPERTY_NAME = "libgraal.java.home" ;
75
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
+
76
82
/**
77
83
* Name of the system property specifying a module path for the module(s) containing
78
84
* {@code LibGraalFeature} and its dependencies that are not available in the runtime image.
@@ -167,30 +173,17 @@ byte[] readBytes() throws ClassNotFoundException {
167
173
/**
168
174
* Modules containing classes that can be annotated by {@code LibGraalService}.
169
175
*/
170
- private static final Set <String > LIBGRAAL_SERVICES_MODULES = Set .of (
176
+ private static final Set <String > LIBGRAAL_MODULES = Set .of (
177
+ "jdk.internal.vm.ci" ,
171
178
"jdk.graal.compiler" ,
172
179
"jdk.graal.compiler.libgraal" ,
173
180
"org.graalvm.truffle.compiler" ,
174
181
"com.oracle.graal.graal_enterprise" );
175
182
176
- /**
177
- * Modules in which Graal and JVMCI classes are defined that this loader will load.
178
- */
179
- private static final Set <String > LIBGRAAL_MODULES = Stream .concat (
180
- LIBGRAAL_SERVICES_MODULES .stream (), Stream .of ("jdk.internal.vm.ci" )) //
181
- .collect (Collectors .toUnmodifiableSet ());
182
-
183
183
static {
184
184
ClassLoader .registerAsParallelCapable ();
185
185
}
186
186
187
- private final Path libgraalJavaHome = Path .of (System .getProperty (LIBGRAAL_JAVA_HOME_PROPERTY_NAME , System .getProperty ("java.home" )));
188
-
189
- @ Override
190
- public Path getJavaHome () {
191
- return libgraalJavaHome ;
192
- }
193
-
194
187
/**
195
188
* Converts the module path entry {@code s} to a {@link Path}.
196
189
*
@@ -207,7 +200,7 @@ Path parseModulePathEntry(String s) {
207
200
@ SuppressWarnings ("unused" )
208
201
public HostedLibGraalClassLoader () {
209
202
// This loader delegates to the class loader that loaded its own class.
210
- super (LibGraalClassLoader . LOADER_NAME , HostedLibGraalClassLoader .class .getClassLoader ());
203
+ super (" LibGraalClassLoader" , HostedLibGraalClassLoader .class .getClassLoader ());
211
204
212
205
try {
213
206
/*
@@ -226,7 +219,7 @@ public HostedLibGraalClassLoader() {
226
219
227
220
Map <String , String > modulesMap = new HashMap <>();
228
221
229
- Path imagePath = libgraalJavaHome .resolve (Path .of ("lib" , "modules" ));
222
+ Path imagePath = LIBGRAAL_JAVA_HOME .resolve (Path .of ("lib" , "modules" ));
230
223
this .imageReader = BasicImageReader .open (imagePath );
231
224
for (var entry : imageReader .getEntryNames ()) {
232
225
int secondSlash = entry .indexOf ('/' , 1 );
@@ -286,15 +279,10 @@ public HostedLibGraalClassLoader() {
286
279
* name of its enclosing module.
287
280
*/
288
281
@ Override
289
- public Map <String , String > getModuleMap () {
282
+ public Map <String , String > getClassModuleMap () {
290
283
return modules ;
291
284
}
292
285
293
- @ Override
294
- public Set <String > getServicesModules () {
295
- return LIBGRAAL_SERVICES_MODULES ;
296
- }
297
-
298
286
@ Override
299
287
protected Class <?> loadClass (String name , boolean resolve ) throws ClassNotFoundException {
300
288
if (!modules .containsKey (name )) {
@@ -328,6 +316,12 @@ protected Class<?> findClass(final String name) throws ClassNotFoundException {
328
316
*/
329
317
private static final String SERVICE_PROTOCOL = "service-config" ;
330
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
+
331
325
/**
332
326
* Name of the protocol for accessing entries in {@link #resources}.
333
327
*/
@@ -341,7 +335,14 @@ protected URL findResource(String name) {
341
335
if (handler == null ) {
342
336
this .serviceHandler = handler = new ImageURLStreamHandler ();
343
337
}
344
- 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/" )) {
345
346
String service = name .substring ("META-INF/services/" .length ());
346
347
if (services .containsKey (service )) {
347
348
try {
@@ -382,7 +383,12 @@ private class ImageURLStreamHandler extends URLStreamHandler {
382
383
@ Override
383
384
public URLConnection openConnection (URL u ) {
384
385
String protocol = u .getProtocol ();
385
- 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 )) {
386
392
List <String > providers = services .get (u .getPath ());
387
393
if (providers != null ) {
388
394
return new ImageURLConnection (u , String .join ("\n " , providers ).getBytes ());
@@ -434,9 +440,4 @@ public String getContentType() {
434
440
return "application/octet-stream" ;
435
441
}
436
442
}
437
-
438
- @ Override
439
- public ClassLoader getRuntimeClassLoader () {
440
- return LibGraalClassLoader .singleton ;
441
- }
442
443
}
0 commit comments