I'm using Byte Buddy in a scenario in which I could potentially need to create several dozen thousand classes with it. These are independent classes implementing interfaces, not proxies.
Right now I'm loading my DynamicType.Unloaded<?>
instances into class loaders by wrapping one of my application's class loaders:
final Class<?> myClass =
unloadedType
.load(someAppClassLoader, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
This wrapping strategy is right for me, but I have the issue that every time I execute the code above a new, sealed ClassLoader
is created containing only the new class. I know I can "include" auxiliary types... but these are not auxiliary types, but fully independent classes.
As I have to create many thousands, I'm left with a huge amount of class loaders I don't really need, because I want to isolate bytebuddy-created classes from the rest, but not one from the other, nor have any need to have a new class loader created for each one. And my profiling shows quite a huge memory overhead from the large amount of class loaders (which in this case are quite heavy).
From my tests it seems I could use a wrapping strategy for the first one:
final Class<?> myClass =
type
.load(someAppClassLoader, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
...then retrieve the new class loader:
final ClassLoader bbClassLoader = myClass.getClassLoader();
...and then use this class loader in subsequent creations, by switching strategy to injection:
final Class<?> myOtherClass =
otherUnloadedType
.load(bbClassLoader, ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
But this does not look like a clean strategy to me given it seems to be injecting via introspection in order to circumvent the fact that the class loader is sealed. So I wonder whether there is a better mechanism for doing this in Byte Buddy.
Note that in order to have a properly sealed class loader I could turn all my many thousands of DynamicType.Unloaded
objects into Class<?>
ones at once into a single class loader instance (and seal it). I can initialise all my classes at application bootstrap in a batch and then leave the class loader alone without further dynamic class creation.
What would be the proper strategy for a scenario like mine?