ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-27 10:04:12  阅读:505  来源: 互联网

标签:stack-overflow aspectj aop aspect java


我正在尝试使用面向方面的编程来执行一个简单的斐波那契函数并跟踪所有对任何调用
方法与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代码,但是如果这样做,您可能会注意到在around()建议本身的方法主体中,IDE显示了AspectJ标记,这意味着它们本身(您的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.

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

您对原始问题的更新明确了您的意图.我已经更新了方面代码以反映这些更改.结果方面将如下所示:

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包中所有对代码的调用.

标签:stack-overflow,aspectj,aop,aspect,java
来源: https://codeday.me/bug/20191027/1943635.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有