Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用byte-buddy在java级别执行指令_Java_Byte Buddy - Fatal编程技术网

使用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)