我正在尝试在Java代理中使用ByteBuddy来使用OpenTracing来检测一些较旧的库。这与OpenTracing Contrib Java Special Agent project相关联。使用私有类成员传递活动范围时,我可以成功完成此工作,但是不幸的是,在某些情况下,这样做不可行(错误处理会清除成员字段)。

因此,我正在尝试使用ByteBuddy的功能来创建可以从@ Advice.OnMethodEnter到@ Advice.OnMethodExit保留的局部变量。这将允许我在方法进入时创建OpenTracing Span,并在方法退出时完成它。我不确定用例是否有效,因为我使用的是转换器,它与@ Advice.Local批注的测试用例不完全匹配。

我试图遵循this test case中使用的语法。

但是,span和scope变量在exit方法中始终为null。我是ByteBuddy的新手,所以我确定我缺少一些基本知识。

public class SimpleFrameworkDispatcherAgentRule extends AgentRule {
    @Override
    public Iterable<? extends AgentBuilder> buildAgent(AgentBuilder agentBuilder) {
        return Arrays.asList(agentBuilder
                .type(named("org.simpleframework.http.core.Dispatcher"))
                .transform((builder, typeDescription, classLoader, module) -> {
                    return builder.visit(Advice.to(SimpleFrameworkDispatcherAgentRule.class)
                            .on(named("dispatch")));
                }));
    }

    @Advice.OnMethodEnter
    public static void enter(final @Advice.Origin String origin,
            final @FieldValue(value = "request", typing = Typing.DYNAMIC) Object request,
            final @Advice.Local("span") Object span,
            final @Advice.Local("scope") Object scope) {
        if (isEnabled(origin)) {
            SimpleFrameworkAgentIntercept.enter(request, span, scope);
        }
    }

    @Advice.OnMethodExit
    public static void exit(final @Advice.Origin String origin,
            final @FieldValue(value = "response", typing = Typing.DYNAMIC) Object response,
            final @Advice.Local("span") Object span,
            final @Advice.Local("scope") Object scope) {
        if (isEnabled(origin)) {
            SimpleFrameworkAgentIntercept.exit(response, span, scope);
        }
    }
}


我检测了SimpleFrameworkAgentIntercept的enter和exit方法,并确认在enter中分配了变量,但在exit中它们为null。

最佳答案

您必须分配变量,如果在委托方法中执行此操作将无济于事。

字节伙伴将建议代码用作模板,其中特定方法中对本地变量的任何分配都转换为对内联字节代码中所检测的本地变量的访问。

Java没有C或其他语言的指针语义。如果要分配spanscope,则必须在带注释的方法本身中进行分配。

10-07 18:58
查看更多