<div dir="ltr"><div>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.<br></div><div><br></div><div>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.</div><div><br></div><div>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?</div><div><br></div><div><div>public InputStream getResourceAsStream(String name, Runtime.Version version) {</div><div> return getResourceAsStream(name);<br></div><div>}</div><div><br></div><div>This would allow MR-aware class loaders an option to expose resources independently of the current JVM version. <br></div><div><br></div><div>Best regards, Rafael<br></div> </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Am So., 22. Sept. 2024 um 20:45 Uhr schrieb Alan Bateman <<a href="mailto:alan.bateman@oracle.com">alan.bateman@oracle.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 22/09/2024 17:45, Rafael Winterhalter wrote:<br>
> That is only true for Class::getResource which resolves resources <br>
> relative to the loaded class's class file location. Java agents <br>
> typically use ClassLoader::getResource(AsStream) as the loaded class <br>
> is not available in the general case of transforming, and not <br>
> retransforming, a class. For example, when instrumenting a newly <br>
> loaded class A in a ClassFileTransformer, it might not be the case <br>
> that its superclass B is loaded. If class B exists in two versions as <br>
> part of a multi-release jar file, currently, you need to query the <br>
> class loader of A as the JVM would do. When loading a class, <br>
> ClassLoader::findClass respects the multi-release characteristic. But <br>
> for ClassLoader::getResource, this is not the case. This is why I want <br>
> to suggest a new method where this is possible, as the intend to <br>
> resolve a class file is explicit. Currently, you need to iterate as <br>
> the ClassLoader does not expose any relevant information.<br>
<br>
If a URLClassLoader is created with a URL to a JAR file then it should <br>
open it as a MR-JAR and getResource should find the .class resources in <br>
the versioned section. Are you saying that this doesn't work? If it <br>
doesn't work then I think it would be useful to show the <br>
getResource(name) output. If the resource is versioned then you end with <br>
"!/META-INF/versions/$N/$R". But maybe this is a different type of <br>
ClassLoader?<br>
<br>
-Alan<br>
<br>
</blockquote></div>