Byte Buddy attempts to avoid class loading during build instrumentation, as this might have side-effects when types are loaded, and described, using the reflection API. Therefore Byte Buddy parses class files itself and offers its own representation. 99.9% of users will be able to provide all relevant class files by pointing to a jar file or a folder with classes, and Byte Buddy will treat this as a form of class path to describe the dependency tree to the build time instrumentation, without loading any classes. As an option for the reminding 0.1%, dependencies can also be provided using a ClassLoader. A case I have encountered more than once is that a custom ClassLoader generates classes on demand if queried. To support this, Byte Buddy then queries the ClassLoader for ".class" files also, without processing a jar file or folder directly.
As of today, I have no way to tell the class loader that the target version of the build plugin is for example Java 17, and that I want the Java 17 version of a class file. I can query for META-INF/versions 8-17 to see if there is a class file for that name (rather inefficient). But if the build is run on a Java 21 JVM and there is a META-INF/versions/21 version of a class, the Java 17 "original" class file is not available to me. This is why I was wondering if there should be a method to query a resource "as if" it was requested for a particular version that is not the current JVM (or JarFile-constructor-supplied) version. Does this describe my problem better? I understand that this really is an edge case. Then again I think this is a legitimate problem that should be solvable. And with a shift towards build-time instrumentation and likely growing adoption of MR JAR files, I would of course want to solve this in Byte Buddy, if given the opportunity. Am Di., 24. Sept. 2024 um 15:23 Uhr schrieb Alan Bateman < alan.bate...@oracle.com>: > On 24/09/2024 11:43, Rafael Winterhalter wrote: > > > > 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? > > > > Tooling that does static instrumentation leads itself to a --release N > option. Assuming this isn't a training runs of sorts it's hard hard to > picture a ClassLoader in that environment. How does the build tool now > what to setup so that it matches the arrangement and visibility of > runtime? Is it really a ClassLoader or something just locates the class > bytes in the same way as a ClassLoader at runtime? > > -Alan >