ClassLoader API to look up class files

Rafael Winterhalter rafael.wth at gmail.com
Tue Sep 24 10:43:44 UTC 2024


Without getting lost in specifics:

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.

With this in mind, class files are read from either:
- A folder
- A JAR file
- A ClassLoader (getResourceAsStream)

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).

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?

Thanks, Rafael

Alan Bateman <alan.bateman at oracle.com> schrieb am Di., 24. Sept. 2024,
08:28:

> On 23/09/2024 20:35, Rafael Winterhalter wrote:
> > 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.
>
> A lot of the direct usages of JarFile will be tools rather than custom
> class loaders so it was important that it be opt-in for this cohort. The
> exploration into compatibility and migration for MR JARs was 8-10 years
> ago. Looking at it now I don't think other defaults would have worked.
>
> In the API docs "Implementation Note" you'll see that system property
> jdk.util.jar.enableMultiRelease can be set to "force" as a migration
> aid, maybe it will be useful here.
>
>
>
> >
> > 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.
> >
> ClassLoader is abstracted away from where the resources are loaded from.
> So a different level from MR JARs.
>
> I think it would be useful for the discussion if you could say more
> about this custom class loader is. Does it extend URLClassLoader, does
> it use JarFile directly, ... From the mails so far it sounds like there
> is something in the picture that is "MR JAR unaware" but it reading
> resources from a MR JAR. It sounds like some operations are locating
> resources in the base section and some in the versioned section.
>
> -Alan
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240924/1121de45/attachment.htm>


More information about the core-libs-dev mailing list