So I tracked down the discrepancy to a changing default for URLClassLoader compared to JarFile. URLClassLoader resolves resources to the "versions" folder for Java 9 and later, even without code changes. This is not the case for JarFile where the relevant version needs to be passed to a new constructor that is introduced in Java 9, requiring code changes.
This creates a new problem to me however: I can look up a META-INF/versions resource in a multi-release jar, when using a class loader, no matter the JVM version. I can however not look up the original "non-META-INF" resource. I have been browsing the source code, and this seems to be impossible, is that right? This again brings me back to my original suggestion. Should there be a method in ClassLoader (and JarFile) that allows locating a resource for a given version? In code instrumentation tools, mostly for build, but also for agents, it can be rather essential to query class file stores for specific versions. I learned in the process that multi-release jars can contain anything, not only classes. Therefore, I wonder if adding a method like the following would be reasonable? public InputStream getResourceAsStream(String name, Runtime.Version version) { return getResourceAsStream(name); } This would allow MR-aware class loaders an option to expose resources independently of the current JVM version. Best regards, Rafael Am So., 22. Sept. 2024 um 20:45 Uhr schrieb Alan Bateman < alan.bate...@oracle.com>: > On 22/09/2024 17:45, Rafael Winterhalter wrote: > > That is only true for Class::getResource which resolves resources > > relative to the loaded class's class file location. Java agents > > typically use ClassLoader::getResource(AsStream) as the loaded class > > is not available in the general case of transforming, and not > > retransforming, a class. For example, when instrumenting a newly > > loaded class A in a ClassFileTransformer, it might not be the case > > that its superclass B is loaded. If class B exists in two versions as > > part of a multi-release jar file, currently, you need to query the > > class loader of A as the JVM would do. When loading a class, > > ClassLoader::findClass respects the multi-release characteristic. But > > for ClassLoader::getResource, this is not the case. This is why I want > > to suggest a new method where this is possible, as the intend to > > resolve a class file is explicit. Currently, you need to iterate as > > the ClassLoader does not expose any relevant information. > > If a URLClassLoader is created with a URL to a JAR file then it should > open it as a MR-JAR and getResource should find the .class resources in > the versioned section. Are you saying that this doesn't work? If it > doesn't work then I think it would be useful to show the > getResource(name) output. If the resource is versioned then you end with > "!/META-INF/versions/$N/$R". But maybe this is a different type of > ClassLoader? > > -Alan > >