Announcement Announcement Module
Collapse
No announcement yet.
Another interesting AOP issue - indefinite loop when multi advices on same pointcut Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Another interesting AOP issue - indefinite loop when multi advices on same pointcut

    I'm using Spring 2.0.6 and run into another interesting issue.

    When I:
    1) use xml schema-based AOP configuration
    2) define a broad pointcut expression like * *(..)
    3) define one "before" advice and one "after-returning" advice and apply them to the same pointcut defined in step 2)

    I got indefinite loop error.

    I realize that there are workarounds like defining a "around" advice instead of multiple "before" and "after" ones. But I still wonder if this is just a bug with Spring AOP or it is a basic restriction with Spring AOP that it is not supposed to be used this way. Any comments will be appreciated.

    ********** code ************
    package test;

    public class Logger
    {
    public void logBefore()
    {
    System.out.println("Log before!");
    }

    public void logAfter()
    {
    System.out.println("Log after!");
    }
    }

    ---

    package test;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlAp plicationContext;

    public class LoggerTarget
    {

    public void doIt()
    {
    System.out.println("do it!");
    }

    public static void main(String args[])
    {
    ApplicationContext context = new ClassPathXmlApplicationContext(
    new String[] { "/context1.xml"});
    LoggerTarget logger = (LoggerTarget) context.getBean("loggerTarget");
    logger.doIt();
    }
    }

    ---

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
    >

    <!-- <bean id="loggerTarget" class="java.lang.Object"/>-->
    <bean id="loggerTarget" class="test.LoggerTarget"/>
    <bean id="logger" class="test.Logger"/>

    <aop:config>
    <aopointcut id="d2" expression="execution(* *(..))"/>
    <aop:aspect ref="logger">
    <aop:before pointcut-ref="d2" method="logBefore"/>
    <aop:after-returning pointcut-ref="d2" method="logAfter"/>
    </aop:aspect>
    </aop:config>

    </beans>

    ******** code over **********

  • #2
    Hi,

    don't know what exactly happens, but the pointcut execution(* *(..)) without any other condition is really strange.
    With that you will end in a indefinite loop (this happens also with aspectj), because the pointcut matches also while executing the advice itself.

    best regards
    agim

    Comment


    • #3
      That's exactly what heppened - the advice got advised on. What I was trying to do was implementing a simple method level execution trace log. It turns out I have to use a pointcut expression something like: * (! package.aspectclass) *(..) to make it (or maybe a few "and" clauses)

      The Spring doc says that when using @AspectJ, the aspect class is automatically excluded from being advised. But I guess the schema-based AOP is a bit different (possibly with its reasons). The bottom line is, it feels like a little bit not intuitive and forcing the developer to know too much about the behind sciene implementation details of Spring AOP to use it.

      Comment


      • #4
        Hello,

        That's exactly what heppened - the advice got advised on. What I was trying to do was implementing a simple method level execution trace log. It turns out I have to use a pointcut expression something like: * (! package.aspectclass) *(..) to make it (or maybe a few "and" clauses)
        Normally i would go to define my pointcuts in a logical way, then normally you will not get this problem. (Because in my projects i have my interceptors in other package then rest of the code).
        For example i would have pointcuts like "withinserviceLayer" or "withinPresentation".

        The Spring doc says that when using @AspectJ, the aspect class is automatically excluded from being advised. But I guess the schema-based AOP is a bit different (possibly with its reasons). The bottom line is, it feels like a little bit not intuitive and forcing the developer to know too much about the behind sciene implementation details of Spring AOP to use it.
        I think Spring behavies like AspectJ, the only difference is the error message.
        for testing with AspectJ i have changed your example a little bit

        I have defined a new AspectJ pointcut that extends your Logger Aspect from your sample

        Code:
        package test;
        
        public aspect LoggingAspect extends Logger {
        
        	
        	pointcut logAllMethods() : execution( * *(..));
        	
        	before() : logAllMethods() {
        		logBefore();
        	}
        	
        	after() returning() : logAllMethods() {
        		logAfter();
        	}
        }
        After that i changed the main class, to use "pure" java

        Code:
        package test;
        
        public class LoggerTarget {
        
        	public void doIt() {
        		System.out.println("do it!");
        	}
        
        	public static void main(String args[]) {
        		new LoggerTarget().doIt();
        	}
        }

        The result is an StackOverFlowerror

        Code:
        Exception in thread "main" java.lang.StackOverflowError
        	at test.Logger.logBefore(Logger.java:5)
        	at test.LoggingAspect.ajc$before$test_LoggingAspect$1$e68748f6(LoggingAspect.aj:9)
        	at test.Logger.logBefore(Logger.java:5)
        
        ..And around 300 line of the same stacktrace...
        So also AspectJ don't prevent you to make such an error.

        Best regards
        agim

        Comment

        Working...
        X