gpt4 book ai didi

java - AOP - 错误 : java. lang.StackOverflowError 在 org.aspectj.runtime.internal.AroundClosure

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:47 24 4
gpt4 key购买 nike

我正在尝试使用面向方面的编程来执行一个简单的斐波那契函数并跟踪对任何除了 Java 中的方法外,还显示嵌套他们的水平。

Java 代码:

package tracing;

public class Test {

static int fib(int n) {
if (n<=1)
return n;
else
return fib(n-1) + fib(n-2);
}

static void report(int n,int r) {
System.out.println("fib("+n+")="+r);
}

public static void main(String[] a) {
report(4,fib(4));
}
}

AspectJ 代码:

package tracing;

public aspect Trace {
String prefix = "";

Object around(): call(* *(..)) && !within(java..*) && !within(FigureEditor..*) {
System.out.println(prefix+thisJoinPoint.getSignature());
prefix = ">" + prefix;
Object result = proceed();
prefix = prefix.substring(1);
return result;
}
}

注意:&& !within(FigureEditor..*) 只是为了避免不同包的类中的函数。


控制台输出 - 错误:

Exception in thread "main" java.lang.StackOverflowError     at
org.aspectj.runtime.internal.AroundClosure.<init>(AroundClosure.java:34)
at tracing.Trace$AjcClosure1.<init>(Trace.aj:1) at
tracing.Trace.ajc$around$tracing_Trace$1$ef88057b(Trace.aj:7) at
tracing.Trace.ajc$around$tracing_Trace$1$ef88057b(Trace.aj:7) at
tracing.Trace.ajc$around$tracing_Trace$1$ef88057b(Trace.aj:7) at
tracing.Trace.ajc$around$tracing_Trace$1$ef88057b(Trace.aj:7) at
tracing.Trace.ajc$around$tracing_Trace$1$ef88057b(Trace.aj:7) at
tracing.Trace.ajc$around$tracing_Trace$1$ef88057b(Trace.aj:7)

更新:我想要的输出类似于以下内容:

void Test.main(String [])
>void Test.report(int, int)<br>
>>int Test.fib(int)<br>
>>>int Test.fib(int)<br>
>>>>int Test.fib(int)<br>
>>>>>int Test.fib(int)<br>
>>>>>int Test.fib(int)<br>
>>>>int Test.fib(int)<br>
>>>int Test.fib(int)<br>
>>>>int Test.fib(int)<br>
>>>>int Test.fib(int)<br>
>> void Test.write(String) fib(4)=3

最佳答案

我不确定您是否正在使用 Eclipse 或其他一些 IDE 来开发您的 AspectJ 代码,但如果您这样做,您可能会注意到 IDE 在您的 的方法体中显示了 AspectJ 标记around() 建议本身,这意味着它们本身(您的 around() 建议中的方法调用)由您的方面编织而成,如下图所示:

AspectJ markers shown in the advice itself

这意味着,为了避免在您的 around() 通知中发生无限递归,在这种情况下,通知会从内部重复调用,您需要从中排除通知的控制流得到建议。您可以通过包含以下切入点表达式轻松地排除任何建议的控制流中的所有代码:!cflow(adviceexecution()) 因此您的方面代码将如下所示(稍微重新格式化):

public aspect Trace {

String prefix = "";

Object around(): call(* *(..))
&& !within(java..*)
&& !within(FigureEditor..*)
&& !cflow(adviceexecution()) {

System.out.println(prefix+thisJoinPoint.getSignature());
prefix = ">" + prefix;
Object result = proceed();
prefix = prefix.substring(1);

return result;
}
}

来自AspectJ documentation on pointcut expressions :

cflow(Pointcut): Picks out each join point in the control flow of any join point P picked out by Pointcut, including P itself.

adviceexecution(): Picks out all advice execution join points.

编辑:添加方面代码以反射(reflect)更新后的问题

您对原始问题的更新阐明了您的意图。我已经更新了方面代码以反射(reflect)这些变化。结果方面将如下所示:

public aspect Trace {

String prefix = "";

Object around(): call(* *(..))
&& !within(java..*)
&& !if(thisJoinPoint.getTarget()!=null && thisJoinPoint.getTarget().getClass().getName().startsWith("java"))
&& !within(FigureEditor..*)
&& !within(Trace) {

System.out.println(prefix+thisJoinPoint.getSignature());
prefix = ">" + prefix;
Object result = proceed();
prefix = prefix.substring(1);

return result;
}
}

我将所有建议执行代码的控制流排除替换为仅排除 Trace 方面,并包含一个运行时测试以排除对 java< 中代码的所有调用 包。

关于java - AOP - 错误 : java. lang.StackOverflowError 在 org.aspectj.runtime.internal.AroundClosure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35486395/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com