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