<p dir="ltr">Without getting lost in specifics:</p>
<p dir="ltr">Byte Buddy allows to transform classes and to store the transformed state. Increasingly, this is done at build time to reduce start up costs and to support AOT compilation. Java agents are the more common option still, but I notice a shift to build time instrumentation, also because of dynamic attach becoming less accessible. One consequence is that the building JVM might not be of the same version as the executing JVM.</p>
<p dir="ltr">With this in mind, class files are read from either:<br>
- A folder<br>
- A JAR file<br>
- A ClassLoader (getResourceAsStream)</p>
<p dir="ltr">In build tools, the last option is rather uncommon, but it exists. I can only assume that the people that requested this use case have good enough reasons for this (probably because URLs are remote and the logic to fetch them is wired into a loader implementation, I am guessing, though).</p>
<p dir="ltr">If the build plugin now wants to create instrumented versions of class files for a Java 17 JVM, while the build is run on a Java 21 JVM, I can support this for JAR files, for folders, but I cannot fetch the adequate resource when the underlying resource accessor is a class loader. I do not think that I can work around this, or do I overlook something?</p>
<p dir="ltr">Thanks, Rafael</p>
<br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Alan Bateman <<a href="mailto:alan.bateman@oracle.com">alan.bateman@oracle.com</a>> schrieb am Di., 24. Sept. 2024, 08:28:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 23/09/2024 20:35, Rafael Winterhalter wrote:<br>
> So I tracked down the discrepancy to a changing default for <br>
> URLClassLoader compared to JarFile. URLClassLoader resolves resources <br>
> to the "versions" folder for Java 9 and later, even without code <br>
> changes. This is not the case for JarFile where the relevant version <br>
> needs to be passed to a new constructor that is introduced in Java 9, <br>
> requiring code changes.<br>
<br>
A lot of the direct usages of JarFile will be tools rather than custom <br>
class loaders so it was important that it be opt-in for this cohort. The <br>
exploration into compatibility and migration for MR JARs was 8-10 years <br>
ago. Looking at it now I don't think other defaults would have worked.<br>
<br>
In the API docs "Implementation Note" you'll see that system property <br>
jdk.util.jar.enableMultiRelease can be set to "force" as a migration <br>
aid, maybe it will be useful here.<br>
<br>
<br>
<br>
><br>
> This creates a new problem to me however: I can look up a <br>
> META-INF/versions resource in a multi-release jar, when using a class <br>
> loader, no matter the JVM version. I can however not look up the <br>
> original "non-META-INF" resource. I have been browsing the source <br>
> code, and this seems to be impossible, is that right? This again <br>
> brings me back to my original suggestion. Should there be a method in <br>
> ClassLoader (and JarFile) that allows locating a resource for a given <br>
> version? In code instrumentation tools, mostly for build, but also for <br>
> agents, it can be rather essential to query class file stores for <br>
> specific versions.<br>
><br>
> I learned in the process that multi-release jars can contain anything, <br>
> not only classes. Therefore, I wonder if adding a method like the <br>
> following would be reasonable?<br>
><br>
> public InputStream getResourceAsStream(String name, Runtime.Version <br>
> version) {<br>
> return getResourceAsStream(name);<br>
> }<br>
><br>
> This would allow MR-aware class loaders an option to expose resources <br>
> independently of the current JVM version.<br>
><br>
ClassLoader is abstracted away from where the resources are loaded from. <br>
So a different level from MR JARs.<br>
<br>
I think it would be useful for the discussion if you could say more <br>
about this custom class loader is. Does it extend URLClassLoader, does <br>
it use JarFile directly, ... From the mails so far it sounds like there <br>
is something in the picture that is "MR JAR unaware" but it reading <br>
resources from a MR JAR. It sounds like some operations are locating <br>
resources in the base section and some in the versioned section.<br>
<br>
-Alan<br>
</blockquote></div>