首页 > 解决方案 > 使用不带 -javaagent 参数的 ByteBuddy Java 代理

问题描述

我正在尝试在项目中检测一些类。当我将代理类打包到一个 jar 中并通过 -javaagent 使用它时,它工作正常。

public static void premain(String arguments, Instrumentation instrumentation) {

        new AgentBuilder.Default()
                .type(ElementMatchers.nameStartsWith("com.cn."))
                .transform((builder, type, cl, m) -> builder
                        .method(ElementMatchers.isAnnotatedWith(Retryable.class))
                        .intercept(to(Retry.class)))
                .installOn(instrumentation);
    }

当我尝试直接在项目中运行它时,检测有时会失败。(我在测试类的静态块中初始化 bytebuddy)。

    static {
        Instrumentation inst = ByteBuddyAgent.install();

        new AgentBuilder.Default()
                .type(ElementMatchers.nameStartsWith("com.cn."))
                .transform((builder, type, cl, m) -> builder
                        .method(ElementMatchers.isAnnotatedWith(Retryable.class))
                        .intercept(to(Retry.class)))
                .installOn(inst);
    }

例如,当我添加此测试时,我的代码不再被拦截。对 try/catch 做同样的事情。

RuntimeException e = Assertions.assertThrows(RuntimeException.class, () -> f.doit("doit foo"));

有没有一种安全的方法可以在没有-javaagent 的情况下在同一个项目中检测类?

项目在 OpenJdk11 上。

标签: javabyte-buddy

解决方案


使用 -javaagent 选项,您将始终确保在安装代理后加载您的类。

如果将代理安装在静态块中,则必须确保在加载要检测的任何类之前执行这段代码。例如。您可以将代理安装在您的主要方法中或主要方法所在的静态块中。


推荐阅读