I've got that public void shutdown() throws IOException {...}
in a third-party library, and I want to modify it so that it additionally does a call like System.out.println("ho hum");
right before its normal activity.
In a sense, we have the trivial case: The class is known not to be loaded yet, so I could load the class file as a resource, run it through ByteBuddy to inser that println
call, then feed the resulting file to the current ClassLoader
and all should be fine.
However, I don't seem to be able to find the relevant API (I can't use premain since creating an agent jar with a premain
function would break our build process).
So, what would be the right approach for that?
You would need to transform an unloaded class, described by a type pool. Assuming that your class is on the class path, you'd need to do something like this:
ClassFileLocator locator = ClassFileLocator.ForClassLoader.ofSystemLoader();
TypeDescription type = TypePool.Default.of(locator).describe(name).resolve();
new ByteBuddy().redefine(type, locator)
.method(...).intercept(...)
.make()
.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION);
This way, you load and inject a class into the system loader before it can be looked up. Do however note that on Java 9+, you should use a method handle lookup for injection as the suggested solution uses unsafe internally.