如何避免使用java.lang.stackoverflowerror递归调用



我有一个建议,该建议在建议中称为类似的方法。我们如何确保建议仅一次和一次调用建议。现在,作为我在建议中调用的方法与所仪器的方法相同,它会递归呼叫,并在java.lang.stackoverflowerror中产生。

 transform(
              new AgentBuilder.Transformer.ForAdvice()
.include(JettyHandlerAdvice.class.getClassLoader())
.advice(named("addFilterWithMapping").and(ElementMatchers.takesArgument(0,named("org.eclipse.jetty.servlet.FilterHolder"))),JettyHandlerAdvice.class.getName())
                        )

建议

@Advice.OnMethodEnter
    private static void before(@Advice.AllArguments Object[] args,  @Advice.Origin("#m") String methodName, @Advice.This Object thiz) {          
        FilterHolder filterHolder = ((org.eclipse.jetty.servlet.ServletHandler)thiz).addFilterWithMapping(XYZFilter.class, "/*", EnumSet.of(javax.servlet.DispatcherType.REQUEST));
    }

字节伙伴是一个代码生成框架,而不是面向方面的。想想将代码复制到目标位置;如果您将仪器进行了硬编码为目标方法,则您看到的堆栈溢出错误将相同。

可以通过添加标志来避免这种情况,例如,您可以在递归调用之前定义将其设置为true的ThreadLocal<Boolean>,例如:

if (!threadLocal.get()) {
  threadLocal.set(true);
  try {
    // your code here.
  } finally {
    threadLocal.set(false);
  }
}

这样,您可以跟踪递归电话。但是,您确实需要某个人管理状态。一种选择是使用Instrumentation接口将属性的持有人类的类别的属性类注入Bootstrap类加载程序。

另外,您可以检查堆栈是否有反复的调用。这不像明确的状态管理那样有效,但是从Java 9开始,您可以使用堆栈Walker API,该API便宜得多,并且可以使此通用。

相关内容

  • 没有找到相关文章

最新更新