ClassLoader API to look up class files
Rafael Winterhalter
rafael.wth at gmail.com
Mon Sep 23 19:35:45 UTC 2024
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.bateman at 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240923/2a755a5f/attachment.htm>
More information about the core-libs-dev
mailing list