问题
I have a code for Thread Pool example as follows
public class RunThreads{
static final int MAX_TASK = 3;
public static void main(String[] args)
{
Runnable r1 = new Task("task 1");
Runnable r2 = new Task("task 2");
Runnable r3 = new Task("task 3");
Runnable r4 = new Task("task 4");
Runnable r5 = new Task("task 5");
ExecutorService pool = Executors.newFixedThreadPool(MAX_TASK);
pool.execute(r1);
pool.execute(r2);
pool.execute(r3);
pool.execute(r4);
pool.execute(r5);
pool.shutdown();
}}
and
class Task implements Runnable{
private String name;
public Task(String s)
{
name = s;
}
public void run()
{
try
{
for (int i = 0; i<=5; i++)
{
if (i==0)
{
Date d = new Date();
SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
System.out.println("Initialization Time for"
+ " task name - "+ name +" = " +ft.format(d));
//prints the initialization time for every task
}
else
{
Date d = new Date();
SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
System.out.println("Executing Time for task name - "+
name +" = " +ft.format(d));
// prints the execution time for every task
}
Thread.sleep(1000);
}
System.out.println(name+" complete");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}}
The i create a small agent for instrument java ThreadPoolExecutor
as follows
public class Agent {
public static void premain(String arguments, Instrumentation instrumentation) {
new AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.type((ElementMatchers.nameContains("ThreadPoolExecutor")))
.transform(
new AgentBuilder.Transformer.ForAdvice()
.include(MonitorInterceptor.class.getClassLoader())
.advice(ElementMatchers.any(), MonitorInterceptor.class.getName())
).installOn(instrumentation);
}}
Can we Instrument java class like ThreadPoolExecutor using Byte Buddy. When i debug ThreadPoolExecutor class working.But when i try this using agent ThreadPoolExecutor class never works.
Edit This is my MonitorInterceptor
public class MonitorInterceptor {
@Advice.OnMethodEnter
static void enter(@Advice.Origin String method) throws Exception {
System.out.println(method);
}
Edit
new AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.with(AgentBuilder.Listener.StreamWriting.toSystemError())
.ignore(none())
.type((ElementMatchers.nameContains("ThreadPoolExecutor")))
.transform((builder, typeDescription, classLoader, module) -> builder
.constructor(ElementMatchers.any())
.intercept(Advice.to(MyAdvice.class))
.method(ElementMatchers.any())
.intercept(Advice.to(MonitorInterceptor.class))
).installOn(instrumentation);
回答1:
Unless you configure it explicitly, Byte Buddy does not instrument core Java classes. You can change that by explicitly setting an ignore matcher that does not exclude such classes.
In this context, it should not be necessary to configure an initialization strategy when using Advice.
You might also want to limit the scope of your advice, right now you intercept any method or constructor.
For finding out what is wrong, you can also define an AgentBuilder.Listener to be notified of errors.
回答2:
Using Rafael Winterhalter answer i get solved this problem. I create an agent as follows ,
new AgentBuilder.Default()
.ignore(ElementMatchers.none())
.type(ElementMatchers.nameContains("ThreadPoolExecutor"))
.transform((builder, type, classLoader, module) -> builder
.visit(Advice.to(ThreadPoolExecutorAdvice.class).on(ElementMatchers.any()))
).installOn(instrumentation);
Using this we can instrument Java class.Form this constructor giving like this
java.util.concurrent.ThreadPoolExecutor$Worker(java.util.concurrent.ThreadPoolExecutor,java.lang.Runnable)
But in code constructor not like that, its is
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
So I expect something like
java.util.concurrent.ThreadPoolExecutor(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue)
I used javassist to get constructor and get its as what byte-buddy gives. So using .ignore(ElementMatchers.none())
and visit(Advice.to(ThreadPoolExecutorAdvice.class).on(ElementMatchers.any()))
we can get all constructors and methods in Java level class
来源:https://stackoverflow.com/questions/49321938/instrument-in-java-level-using-byte-buddy