On Tue, Sep 24, 2024 at 1:44 PM Eirik Bjørsnøs <eir...@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; }