Slf4j loggers with Byte Buddy

2019-08-17 17:37发布

I try to instrument a java class called ThreadPoolExecutor and i want to get details of threads using slf4j loggers and I am getting following error

Exception in thread "pool-2-thread-2" Exception in thread "pool-2-thread-1" java.lang.NoClassDefFoundError: com/github/shehanperera/threadagent/MonitorInterceptor
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
    at java.lang.Thread.run(Thread.java:748)java.lang.NoClassDefFoundError: com/github/shehanperera/threadagent/MonitorInterceptor
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
    at java.lang.Thread.run(Thread.java:748)

And this is my Agent

new AgentBuilder.Default()
            .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
            .ignore(ElementMatchers.none())
            .type(ElementMatchers.nameContains("ThreadPoolExecutor"))
            .transform((builder, type, classLoader, module) -> builder
                    .method(ElementMatchers.nameContains("run"))
                    .intercept(Advice.to(MonitorInterceptor.class))
            ).installOn(instrumentation);

And My MonitorInterceptor

public class MonitorInterceptor {

public static Logger logger = LoggerFactory.getLogger(MonitorInterceptor.class.getName());

@Advice.OnMethodEnter
static void enter(@Advice.Origin String method) throws Exception {

    logger.info(String.valueOf(Arrays.asList(Thread.currentThread().getStackTrace())));
}}

logger works normal way and without logger this works. When i try to use logger in enter method like above error will occurs. Any suggestion on This!

1条回答
▲ chillily
2楼-- · 2019-08-17 18:24

If you use a class as Advice, this class is only a template and not code that is actually executed. This means that you must not reference fields that are invisible to the executing method such as the logger field in your class.

Since You are instrumenting a class of the JVM, this class will be loaded on the boot path which cannot see your class path where classes such as SLF4j will be loaded. If you want to add classes to the boot path, you have to do so explicitly. Have a look into Instrumentation::appendToBootstrapClassLoaderSearch for doing so.

查看更多
登录 后发表回答