I am making a plugin system and i need to see when a plugin calls Thread.start() Is there a way similar to Runtime.getRuntime().addShutdownHook but for hooking when a thread starts?
Advertisement
Answer
Byteman
You can use Byteman to inject your own code into the thread.start() method.
In fact, the first example to using Byteman with JVM classes on their website is one showing how to print to the console when a thread has started.
Byteman script example from their tutorial:
RULE trace thread start CLASS java.lang.Thread METHOD start() IF true DO traceln("*** start for thread: "+ $0.getName()) ENDRULE
See https://developer.jboss.org/docs/DOC-17213#how_do_i_inject_code_into_jvm_classes for further implementation details.
ByteBuddy
If Byteman isn’t your thing, there’s another library called ByteBuddy which can be used to create a Java Agent that intercepts a method in the Thread class.
public class ThreadMonitor { @RuntimeType public static Object intercept(@Origin Method method, @SuperCall Callable<?> callable) { System.out.println("A thread start method called"); return callable.call(); //Calling the original start method. } } public class ThreadMonitorAgent { public static void premain(String arguments, Instrumentation instrumentation) { new AgentBuilder.Default() .type(ElementMatchers.nameEndsWith("start")) .transform((builder, type, classLoader, module) -> builder.method(ElementMatchers.any()) .intercept(MethodDelegation.to(ThreadMonitor.class)) ).installOn(instrumentation); } }
Example code adapted from ByteBuddy github readme.