how to avoid recursive calls with byte buddy - java.lang.StackOverflowError

蓝咒 提交于 2019-12-13 18:26:34

问题


I have an advice which calls a similar method in the advice. How do we make sure the advice gets called once and only once. Right now as the method I am calling within advice is the same as the one being instrumented, it goes into recursive calling and results in 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

@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));
    }

回答1:


Byte Buddy is a code generation framework and is not aspect-oriented. Think of the code being copy-pasted to the target location; the stack overflow error you are seing would be the same if you hardcoded the instrumentation into your target method.

This can be avoided by adding a flag, for example, you could define a ThreadLocal<Boolean> that you set to true before making a recursive call, for example:

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

This way, you can keep track of a recursive call. You do however need to manage your state somehome. One option would be to inject a holder class for your property into the bootstrap class loader using the Instrumentation interface.

Alternatively, you can check the stack for a recurive call. This is not as efficient as the explicit state management but starting with Java 9, you can use the stack walker API which is much cheaper and makes this approachable.



来源:https://stackoverflow.com/questions/43540934/how-to-avoid-recursive-calls-with-byte-buddy-java-lang-stackoverflowerror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!