The runtime resources are handled in a backwards compatible way. E.g. when you did
URL url = Object.class.getResource("Object.class");
System.out.println(url);
in the past, you usually got something like
jar:file:/path-to-jre/lib/rt.jar!/java/lang/Object.class
Running the same under Java 9 will give you
jrt:/java.base/java/lang/Object.class
instead. In either case, you can open a FileSystem
on it to inspect the other available resources (since Java 7). While the ZipFileSystem
had to be created via FileSystems.newFileSystem
first, Java 9’s file system is even already open for use:
private static void readMyOwnJRE() throws IOException {
try {
Path p = Paths.get(URI.create("jrt:/")).resolve("/modules");
System.out.println("My own JRE's modules:");
Files.list(p).forEach(m -> System.out.println(m.getFileName()));
System.out.println();
} catch(FileSystemNotFoundException ex) {
System.out.println("Could not read my modules (perhaps not Java 9?).");
}
}
If you are running under a different JRE than the one you want to inspect, you have to load the appropriate file system implementation manually first, but this opens the possibility to inspect a Java 9 installation even from a Java 8 JRE:
public static void readOtherJRE(Path pathToJRE) throws IOException {
Path p = pathToJRE.resolve("lib").resolve("jrt-fs.jar");
if(Files.exists(p)) {
try(URLClassLoader loader = new URLClassLoader(new URL[]{ p.toUri().toURL() });
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
Collections.emptyMap(),
loader)) {
System.out.println("Modules of "+pathToJRE);
Files.list(fs.getPath("/modules")).forEach(System.out::println);
System.out.println();
}
}
}
Once you have a file system (or a Path
into it), you can use all standard functions of, e.g. Files
to inspect or extract/copy the data, though the right term would be “to store an equivalent class file” in a different file system, as the runtime image’s representation doesn’t have to be a class file at all.