使用byte-buddy在java级别执行指令
我有一个线程池示例代码,如下所示使用byte-buddy在java级别执行指令,java,byte-buddy,Java,Byte Buddy,我有一个线程池示例代码,如下所示 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
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();
}}
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);
}}
及
我们可以使用Byte Buddy为java类注入工具,比如ThreadPoolExecutor。当我调试ThreadPoolExecutor类工作时。但当我尝试使用代理ThreadPoolExecutor类时,它永远不会工作
编辑
这是我的监听器
public class MonitorInterceptor {
@Advice.OnMethodEnter
static void enter(@Advice.Origin String method) throws Exception {
System.out.println(method);
}
编辑
除非您显式地配置它,否则Byte Buddy不会为核心Java类提供工具。您可以通过显式设置不排除此类类的ignore matcher来改变这一点 在这种情况下,在使用Advice时不必配置初始化策略 您可能还想限制建议的范围,现在您可以拦截任何方法或构造函数
为了找出错误,您还可以定义一个AgentBuilder.Listener来通知错误。使用Rafael Winterhalter answer,我解决了这个问题。我创建了一个代理,如下所示
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);
使用这个我们可以为Java类提供工具
java.util.concurrent.ThreadPoolExecutor$Worker(java.util.concurrent.ThreadPoolExecutor,java.lang.Runnable)
但在代码构造函数中不是这样的,它是
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
我使用javassist获取构造函数,并将其作为buddy提供的字节。因此,使用
.ignore(ElementMatchers.none())
和访问(Advice.to(ThreadPoolExecutorAdvice.class).on(ElementMatchers.any())
我们可以获得Java级类中的所有构造函数和方法我添加了一个监听器,如下所示发现java.util.concurrent.ThreadPoolExecutor$Worker[null,null,loaded=false][Byte Buddy]忽略java.util.concurrent.ThreadPoolExecutor$Worker[null,null,loaded=false][Byte Buddy]完成java.util.concurrent.ThreadPoolExecutor$Worker[null,null,loaded=false]
。可以吗。因此,我认为它忽略了java类您是否尝试在生成器中忽略(none())`.ignore(ElementMatchers.none())`我使用了这个,我希望我的问题现在得到了解决。我遇到了另一个问题,它没有显示线程池执行器的构造函数
我是否需要添加构造函数(ElementMatchers.any())
这取决于您的仪表现在的状态
java.util.concurrent.ThreadPoolExecutor$Worker(java.util.concurrent.ThreadPoolExecutor,java.lang.Runnable)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
java.util.concurrent.ThreadPoolExecutor(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue)