Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AOP-错误:org.aspectj.runtime.internal.AroundClosure上的java.lang.StackOverflower错误_Java_Stack Overflow_Aop_Aspectj_Aspect - Fatal编程技术网

AOP-错误:org.aspectj.runtime.internal.AroundClosure上的java.lang.StackOverflower错误

AOP-错误:org.aspectj.runtime.internal.AroundClosure上的java.lang.StackOverflower错误,java,stack-overflow,aop,aspectj,aspect,Java,Stack Overflow,Aop,Aspectj,Aspect,我试图使用面向方面的编程来执行一个简单的斐波那契函数,并跟踪对任何 方法,并显示嵌套 他们的水平 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(

我试图使用面向方面的编程来执行一个简单的斐波那契函数,并跟踪对任何 方法,并显示嵌套 他们的水平

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));
    }
}
注意:
&&!在(FigureEditor..*)
中仅用于避免不同包的类中的函数


控制台输出-错误:

线程“main”java.lang.StackOverflower中的异常位于 org.aspectj.runtime.internal.AroundClosure.(AroundClosure.java:34) 在tracing.Trace$AjcClosure1.(Trace.aj:1)在 tracing.Trace.ajc$大约$tracing\u Trace$1$ef88057b(Trace.aj:7)在 tracing.Trace.ajc$大约$tracing\u Trace$1$ef88057b(Trace.aj:7)在 tracing.Trace.ajc$大约$tracing\u Trace$1$ef88057b(Trace.aj:7)在 tracing.Trace.ajc$大约$tracing\u Trace$1$ef88057b(Trace.aj:7)在 tracing.Trace.ajc$大约$tracing\u Trace$1$ef88057b(Trace.aj:7)在 tracing.Trace.ajc$大约$tracing\u Trace$1$ef88057b(Trace.aj:7)
更新:我想要的输出类似于以下内容:

void Test.main(字符串[])
>无效测试报告(int,int)
>>int测试。fib(int)
>>>int测试。fib(int)
>>>>int测试。fib(int)
>>>>>int测试。fib(int)
>>>>>int测试。fib(int)
>>>>int测试。fib(int)
>>>int测试。fib(int)
>>>>int测试。fib(int)
>>>>int测试。fib(int)
>>无效测试。写入(字符串)fib(4)=3
我不确定您是否正在使用Eclipse或其他IDE来开发AspectJ代码,但如果使用了,您可能会注意到IDE在
around()
通知本身的方法体中显示了AspectJ标记,这意味着它们本身(该方法在
around()
通知内部调用)根据您的方面进行编织,如下图所示:

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

从:

cflow(Pointcut)
:在由Pointcut选择的任何连接点p的控制流中选择每个连接点,包括p本身

adviceexecution()
:选择所有通知执行连接点

编辑:添加方面代码以反映更新的问题

您对原始问题的更新澄清了您对方面的意图。我已经更新了方面代码以反映这些更改。由此产生的方面如下所示:

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

我将排除所有通知执行代码的控制流替换为仅排除
跟踪
方面,并包括了一个运行时测试,以排除
java
包中的所有代码调用。

虽然Nándor的答案是正确的,但由于控制流切入点(如
cflow())也很昂贵
cflowDown()
在运行时进行计算。我建议您只需使用
!在(Trace)
中,可以在编译时对其进行评估,而且速度更快

您还希望使用一种更简单的方法来排除对Java类的调用,而不涉及任何反射:
!调用(*java..*(..))

包跟踪;
公共方面跟踪{
字符串前缀=”;
对象周围():
!在(跟踪范围内)&&
呼叫(**(..)&&
!call(*java..*(..)&&
!在(图编辑器..*)内
{
System.out.println(前缀+thisJoinPoint.getSignature());
前缀=“>”+前缀;
对象结果=继续();
前缀=前缀。子字符串(1);
返回结果;
}
}
这将产生所需的输出:

int跟踪.Test.fib(int)
>int跟踪.Test.fib(int)
>>int跟踪.Test.fib(int)
>>>int跟踪.Test.fib(int)
>>>int跟踪.Test.fib(int)
>>int跟踪.Test.fib(int)
>int跟踪.Test.fib(int)
>>int跟踪.Test.fib(int)
>>int跟踪.Test.fib(int)
无效跟踪测试报告(int,int)
fib(4)=3

我已经更新了我的问题,看看我想要的输出是什么。。。。现在执行的很好,没有问题。。。但我得到的结果是:
int tracing.Test.fib(int)void tracing.Test.report(int,int)fib(4)=3
我在我的答案中添加了细节,以反映你问题中的变化。@NándorElődFekete:你认为我的答案如何?我认为它比你的要简单得多,不涉及运行时检查或反射。@kriegaex你完全正确。我的解决方案是次优的。你的答案很完美。我已经解决了你的格式问题。代码格式的语法是缩进4个空格,您也应该在控制台日志中使用它,而不是引用语法“>”。这很好。。我会记住有关
cflow()
cflowdown()
的信息。
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;
    }
}
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;
    }
}