ClassLoader API to look up class files

Rafael Winterhalter rafael.wth at gmail.com
Tue Sep 24 12:48:20 UTC 2024


When the ClassLoader API is used in build plugins, this often serves as a
fallback to non-standardized class storage where the retrieval
implementation is bound to the ClassLoder API. I would have to guess but I
would not assume that many of them use a JarInputStream as a backing
mechanism. By my experience, custom class loaders typically load classes
via TCP.

One use case I remember is a class loader that queried a server which
loaded jars via a URLClassLoader and served class files on demand. In such
a case, it would also be relevant that the resource would be consistent
with the client JVM version, not the server one. Updating the server alone
would result in different resources. Of course, using JarFile to access
resources would be the better option here, but ideally one could adapt MR
jars without larger rewrites. URLClassLoder accepts URLs while JarFile
requires File, what might result in a non-trivial rewrite, for example if
there's multiple hoops.

I don't think this is a large issue either, rather an edge case, otherwise
I would have stumbled over this earlier. The main issue is that Java 8
always allows me to access META-INF resources and the original class file
via the ClassLoder API. Starting from Java 9, the original class file might
be shadowed and inaccessible. So a build might yield a different result
after updating the JDK, and currently I do not see a way to resolve this
backwards compatible. Therefore I was wondering if a new API should adress
this. In JarFile, you can iterate over all resources, including those that
are shadowed, at least. It is something like that that I am looking for.

As for a public issue: I recently had an unrelated issue on MR JARs in
builds what made me aware of this possibility of encountering MR jar files
through ClassLoader class file locators in build plugins, which is a
combination of two rare events that nobody complained about before. But I
could not point you to an old ticket.

Eirik Bjørsnøs <eirbjo at gmail.com> schrieb am Di., 24. Sept. 2024, 13:44:

> On Tue, Sep 24, 2024 at 12:44 PM Rafael Winterhalter <rafael.wth at gmail.com>
> wrote:
>
>> Without getting lost in specifics:
>>
> It is also possible to get very lost by lacking specifics :-)
>
>> 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, this narrows down your use case considerably and also explains why
> you would be interested in loading resources of versions different than the
> runtime version.
>
> Does the class loader in question return JAR-form URLs? If that's the
> case, you could use JarURLConnection.getJarFile() and use getInputStream to
> get the versioned resource of choice:
>
> ClassLoader loader = new URLClassLoader(new URL[] {zip.toUri().toURL()});
> URL resource = loader.getResource(baseName);
> if (resource.openConnection() instanceof JarURLConnection con) {
>     try (var is = con.getJarFile().getInputStream(new
> ZipEntry(baseName))) {
>         assertArrayEquals("base".getBytes(StandardCharsets.UTF_8),
>                 is.readAllBytes());
>     }
> }
>
> Or just parse the URL to find the path to the JAR file and open it using
> ZipFile/JarFile APIs.
>
> Is the issue reported to Byte Buffy publicly available?
>
> Thanks,
> Eirik.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240924/a9cf8a05/attachment.htm>


More information about the core-libs-dev mailing list