ClassLoader API to look up class files
Eirik Bjørsnøs
eirbjo at gmail.com
Tue Sep 24 12:42:27 UTC 2024
On Tue, Sep 24, 2024 at 1:44 PM Eirik Bjørsnøs <eirbjo at gmail.com> wrote:
> Does the class loader in question return JAR-form URLs? If that's the
> case, you could use JarURLConnection.getJarFile() and use getInputStream to
> get the versioned resource of choice:
>
If you also want to offload the version lookup logic to JarFile, re-open
the JarFile with the desired runtime version, like in the following test:
@Test
public void readVersionedResourceFromClassLoader() throws IOException {
// Base name of the class file resource looked up in this test
String baseName = "com/example/HelloWorld.class";
// Create a multi-release JAR file including a versioned entry
Path zip = createMultiReleaseJar(baseName);
// A class loader backed by the multi-release JAR file
ClassLoader loader = new URLClassLoader(new URL[]
{zip.toUri().toURL()});
// The version to get resources for
Runtime.Version version = Runtime.Version.parse("17");
URL resource = loader.getResource(baseName);
if (resource != null && resource.openConnection() instanceof
JarURLConnection con) {
File file = new File(con.getJarFile().getName());
// Open a JarFile for the desired runtime version
try (JarFile jf = new JarFile(file, true, ZipFile.OPEN_READ,
version)) {
JarEntry entry = jf.getJarEntry(baseName);
assertEquals(baseName, entry.getName());
assertEquals("META-INF/versions/11/" + baseName,
entry.getRealName());
try (var is = jf.getInputStream(entry)) {
assertEquals("11", new String(is.readAllBytes()));
}
}
}
}
private static Path createMultiReleaseJar(String baseName) throws
IOException {
Path zip = Path.of("multi-release.zip");
Manifest man = new Manifest();
Attributes attrs = man.getMainAttributes();
attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
attrs.put(Attributes.Name.MULTI_RELEASE, "true");
try (JarOutputStream jo = new
JarOutputStream(Files.newOutputStream(zip), man)) {
jo.putNextEntry(new ZipEntry("META-INF/versions/11/" + baseName));
jo.write("11".getBytes(StandardCharsets.UTF_8));
jo.putNextEntry(new ZipEntry(baseName));
jo.write("base".getBytes(StandardCharsets.UTF_8));
}
return zip;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240924/72f21a1c/attachment-0001.htm>
More information about the core-libs-dev
mailing list