StackOverflow error

View: New views
7 Messages — Rating Filter:   Alert me  

StackOverflow error

by jacknjill111 () :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Environment:
AspectJ 1.6.0
JDK 6u10

Background info:
I've coded an Aspect that would run a particular method a specific number of times. I've created an annotation that can be used to annotate any method that you want to run multiple times

RunMultipleAspectTestApp is the driver class. When I set the RunMultiple.counter to something less than 900, it works great.  
But when I raise it to 1000 or more, I get a java.lang.StackOverflow error. I googled and saw that StackOverFlow error occur
due to infinite recursion as noted in this document: http://www.eclipse.org/aspectj/doc/released/faq.html#q:infiniterecursion
Do I have my pointcut defined incorrectly? Could someone please help me with the pointcut definition for the "repeat" advice?
 

************ RunMultipleAspectTestApp.java - START **************

package com.xxxx.aop.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xxxx.util.annotation.RunMultiple;

public class RunMultipleAspectTestApp {

        private final Log logger = LogFactory.getLog(getClass());

        public static void main(String[] args) {
                RunMultipleAspectTestApp rmata = new RunMultipleAspectTestApp();

                rmata.runMe();
                rmata.runMe("Hello", "World");
        }

        @RunMultiple
        public void runMe() {
                if (logger.isDebugEnabled()) {
                        logger.debug("Hello Jack");
                }
        }

        @RunMultiple(counter = 950)
        public void runMe(String greeting, String name) {
                if (logger.isDebugEnabled()) {
                        logger.debug(greeting + " " + name);
                }
        }
}

************ RunMultipleAspectTestApp.java - END **************


************ RunMultiple.java - START **************

package com.xxxx.util.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunMultiple {
        /**
         * Number of times a method should be invoked
         */
        int counter() default 1;
}

************ RunMultiple.java - END**************

The RunMultipleAspect has a repeat (After) advice which is called on any method annotated with the RunMultiple annotation. RunMultipleAspect
also intercepts object construction (AfterReturning) and caches the object that is created so it can reuse the object in the repeat advice.
The repeat advice looks up the RunMultiple.counter value and then invokes the object method if 'RunMultipleAspect.count < RunMultiple.counter'

************ RunMultipleAspect.java - START **************

package com.xxxx.aop.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;

import com.xxxx.util.annotation.RunMultiple;

/**
 * Aspect to replace the following construct
 *
 *  ...
 *  int counter = 10000;  
 *  for (int i=0; i < counter; i++) {
 *    greet();      
 *  }
 *  
 *   public void greet() {
 *      ...
 *      ...
 *   }  
 *  
 *  with this construct:
 *  
 *  @RunMultiple(counter=10000)
 *  public void greet() {
 *     ...  
 *  }
 *  
 */  

@Aspect
public class RunMultipleAspect {

        private final Log logger = LogFactory.getLog(getClass());

        private int count = 0; // keeps track of how many times a method has been executed
        private String methodName; // keeps track of method name since we could have multiple (overloaded) methods annotated
        private Object obj; // object instance that was created once

        @After("execution(@com.xxxx.util.annotation.RunMultiple * *.*(..)) && !within(RunMultipleAspect)")
        public void repeat(JoinPoint jp) throws ClassNotFoundException,
                        IllegalArgumentException, IllegalAccessException,
                        InvocationTargetException, InstantiationException {
                Method method = ((MethodSignature) jp.getSignature()).getMethod();

                printArguments(jp);

                // doing this to store the current method name
                String tempMethodName = jp.getTarget().getClass().getName() + "."
                                + method.getName() + this.getArgumentTypes(jp);
                if (!tempMethodName.equals(methodName)) {
                        this.methodName = jp.getTarget().getClass().getName() + "."
                                        + method.getName() + this.getArgumentTypes(jp);
                        this.count = 0;
                }

                RunMultiple rmAnnotation = method.getAnnotation(RunMultiple.class);
                if (logger.isTraceEnabled()) {
                        logger.trace("rmAnnotation.toString(): " + rmAnnotation.toString());
                }

                if (logger.isTraceEnabled()) {
                        logger.trace("count: " + count + " :: " + rmAnnotation.counter());
                }
                if (++count < rmAnnotation.counter()) {
                        if (logger.isTraceEnabled()) {
                                logger.trace("using object " + obj.hashCode());
                                logger.trace(obj.getClass().getName() + "." + method.getName());
                        }
                        method.invoke(obj, jp.getArgs());
                }
        }
       
  /**
   * Stores the object instance in 'obj' the first time it is created so I can
   * call methods on that instance    
   */    
        @AfterReturning("execution(*.new(..)) && !within(RunMultipleAspect)")
        public void setObjectAtConstruction(JoinPoint jp) {
                if (logger.isTraceEnabled()) {
                        logger.trace("jp.getTarget(): " + jp.getTarget().hashCode()
                                        + ", jp.getThis(): " + jp.getThis().hashCode());
                }

                if (obj == null) {
                        this.obj = jp.getTarget();
                        if (logger.isTraceEnabled()) {
                                logger.trace("creating object: " + obj.hashCode());
                        }
                } else {
                        if (logger.isTraceEnabled()) {
                                logger.trace("object created earlier: " + obj.hashCode());
                        }
                }
        }
       

        private String getArgumentTypes(JoinPoint jp) {
                Class<?>[] argTypes = ((CodeSignature) jp.getSignature())
                                .getParameterTypes();

                if (argTypes != null && argTypes.length > 0) {
                        StringBuilder sb = new StringBuilder("(");
                        for (int ar = 0; ar < argTypes.length; ar++) {
                                sb.append(argTypes[ar].getName());
                                if (ar < argTypes.length - 1) {
                                        sb.append(",");
                                }
                        }
                        sb.append(")");

                        return sb.toString();
                }

                return "";
        }

        private void printArguments(JoinPoint jp) {
                Object[] args = jp.getArgs();
                String[] argNames = ((CodeSignature) jp.getSignature())
                                .getParameterNames();
                Class<?>[] argTypes = ((CodeSignature) jp.getSignature())
                                .getParameterTypes();

                for (int i = 0; i < args.length; i++) {
                        if (logger.isTraceEnabled()) {
                                logger.trace(argTypes[i].getName() + "." + argNames[i] + "="
                                                + args[i]);
                        }
                }

        }


}

************ RunMultipleAspect.java - END **************

My aop.xml looks like this:

<aspects>

        <aspect name="com.xxxx.aop.util.RunMultipleAspect" />
       
        <weaver options="-verbose -showWeaveInfo -debug">
                <include within="com.xxxx.aop.util..*" />
                <exclude within="com.xxxx.aop.util.RunMultipleAspect" />
        </weaver>

</aspects>

******************** Output/Error log: **************************
[AppClassLoader@fabe9] info AspectJ Weaver Version 1.6.0 built on Wednesday Apr 23, 2008 at 20:27:36 GMT
[AppClassLoader@fabe9] info register classloader sun.misc.Launcher$AppClassLoader@fabe9
[AppClassLoader@fabe9] info using configuration /home/roshan/myProjects/xxxx-common/target/classes/META-INF/aop.xml
[AppClassLoader@fabe9] info register aspect com.xxxx.aop.util.RunMultipleAspect
[AppClassLoader@fabe9] debug weaving 'com.xxxx.aop.util.RunMultipleAspectTestApp'
[AppClassLoader@fabe9] weaveinfo Join point 'constructor-execution(void com.xxxx.aop.util.RunMultipleAspectTestApp.<init>())' in Type 'com.xxxx.aop.util.RunMultipleAspectTestApp' (RunMultipleAspectTestApp.java:10) advised by afterReturning advice from 'com.xxxx.aop.util.RunMultipleAspect' (RunMultipleAspect.java)
[AppClassLoader@fabe9] weaveinfo Join point 'method-execution(void com.xxxx.aop.util.RunMultipleAspectTestApp.runMe())' in Type 'com.xxxx.aop.util.RunMultipleAspectTestApp' (RunMultipleAspectTestApp.java:42) advised by after advice from 'com.xxxx.aop.util.RunMultipleAspect' (RunMultipleAspect.java)
[AppClassLoader@fabe9] weaveinfo Join point 'method-execution(void com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(java.lang.String, java.lang.String))' in Type 'com.xxxx.aop.util.RunMultipleAspectTestApp' (RunMultipleAspectTestApp.java:49) advised by after advice from 'com.xxxx.aop.util.RunMultipleAspect' (RunMultipleAspect.java)
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.Factory'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.SourceLocation'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.MethodSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.MethodSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.CodeSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.MemberSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.SignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.ConstructorSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.ConstructorSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.UnlockSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.UnlockSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.LockSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.LockSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.AdviceSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.AdviceSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.CatchClauseSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.CatchClauseSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.FieldSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.FieldSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.InitializerSignatureImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.reflect.InitializerSignature'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.SignatureImpl$Cache'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.JoinPointImpl$StaticPartImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.SourceLocationImpl'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.runtime.reflect.JoinPointImpl'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogConfigurationException'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory$6'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.WeakHashtable'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory$1'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.WeakHashtable$Referenced'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.WeakHashtable$WeakKey'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory$4'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory$5'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory$3'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.LogFactory$2'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.LogFactoryImpl'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.LogFactoryImpl$2'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.LogFactoryImpl$1'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.SimpleLog'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.Log'
[AppClassLoader@fabe9] debug not weaving 'org.apache.commons.logging.impl.SimpleLog$1'
[AppClassLoader@fabe9] debug weaving 'com.xxxx.aop.util.RunMultipleAspect'
[AppClassLoader@fabe9] debug cannot weave 'org.aspectj.lang.NoAspectBoundException'
2008/07/02 23:51:01:271 CDT [TRACE] RunMultipleAspect - jp.getTarget(): 9299042, jp.getThis(): 9299042
2008/07/02 23:51:01:278 CDT [TRACE] RunMultipleAspect - creating object: 9299042
2008/07/02 23:51:01:278 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
[AppClassLoader@fabe9] debug not weaving 'com.xxxx.util.annotation.RunMultiple'
[AppClassLoader@fabe9] debug not weaving '$Proxy3'
2008/07/02 23:51:01:308 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=1, repeat=true)
2008/07/02 23:51:01:309 CDT [TRACE] RunMultipleAspect - count: 0 :: 1
2008/07/02 23:51:01:309 CDT [DEBUG] RunMultipleAspectTestApp - Hello Rosh
2008/07/02 23:51:01:309 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 23:51:01:309 CDT [TRACE] RunMultipleAspect - java.lang.String.name=Rosh
2008/07/02 23:51:01:310 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950, repeat=true)
2008/07/02 23:51:01:310 CDT [TRACE] RunMultipleAspect - count: 0 :: 950
2008/07/02 23:51:01:310 CDT [TRACE] RunMultipleAspect - using object 9299042
2008/07/02 23:51:01:311 CDT [DEBUG] RunMultipleAspectTestApp - Hello Rosh
2008/07/02 23:51:01:311 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 23:51:01:311 CDT [TRACE] RunMultipleAspect - java.lang.String.name=Rosh
2008/07/02 23:51:01:311 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950, repeat=true)
2008/07/02 23:51:01:311 CDT [TRACE] RunMultipleAspect - count: 1 :: 950
2008/07/02 23:51:01:311 CDT [TRACE] RunMultipleAspect - using object 9299042
2008/07/02 23:51:01:312 CDT [DEBUG] RunMultipleAspectTestApp - Hello Rosh
2008/07/02 23:51:01:312 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 23:51:01:312 CDT [TRACE] RunMultipleAspect - java.lang.String.name=Rosh
2008/07/02 23:51:01:312 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950, repeat=true)
2008/07/02 23:51:01:312 CDT [TRACE] RunMultipleAspect - count: 2 :: 950
2008/07/02 23:51:01:312 CDT [TRACE] RunMultipleAspect - using object 9299042
2008/07/02 23:51:01:313 CDT [DEBUG] RunMultipleAspectTestApp - Hello Rosh
2008/07/02 23:51:01:313 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 23:51:01:313 CDT [TRACE] RunMultipleAspect - java.lang.String.name=Rosh
....
....
....
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 929 :: 950
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object 14779369
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - java.lang.String.name=World
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 930 :: 950
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object 14779369
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - java.lang.String.name=World
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 931 :: 950
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object 14779369
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - java.lang.String.greeting=Hello
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - java.lang.String.name=World
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 932 :: 950
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object 14779369
2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.main(RunMultipleAspectTestApp.java:16)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        ... 7 more
.......
.......
.......
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        ... 1012 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        ... 1017 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
........
........
........
Caused by: java.lang.reflect.InvocationTargetException
        ... 1024 more
Caused by: java.lang.reflect.InvocationTargetException
        ... 1024 more
Caused by: java.lang.StackOverflowError
        at java.text.DecimalFormat.subformat(Unknown Source)
        at java.text.DecimalFormat.format(Unknown Source)
        at java.text.DecimalFormat.format(Unknown Source)
        at java.text.SimpleDateFormat.zeroPaddingNumber(Unknown Source)
        at java.text.SimpleDateFormat.subFormat(Unknown Source)
        at java.text.SimpleDateFormat.format(Unknown Source)
        at java.text.SimpleDateFormat.format(Unknown Source)
        at java.text.DateFormat.format(Unknown Source)
        at org.apache.commons.logging.impl.SimpleLog.log(SimpleLog.java:294)
        at org.apache.commons.logging.impl.SimpleLog.trace(SimpleLog.java:416)
        at com.xxxx.aop.util.RunMultipleAspect.printArguments(RunMultipleAspect.java:175)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:115)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
        at com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)




Any help is greatly appreciated.

Re: StackOverflow error

by Andy Clement :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

You have advised runMe() to execute your advice:

       @RunMultiple(counter = 1000)
       public void runMe(String greeting, String name) {
               if (logger.isDebugEnabled()) {
                       logger.debug(greeting + " " + name);
               }
       }

Your advice then says if count is less than the annotation value
counter, call runMe().  This will invoke the advised version of
runMe(greeting,name).  And then we will come back into the aspect and
do it again, and so on and so on. Did you really want to call the
advised version of runMe() - I guess you did from the aspect
structure.  This recursion only stops when count is finally greater
than counter.  The JVM can handle a certain level of recursion before
it just gives up and throws StackOverflow - and your 1000 number seems
to be the point where it is giving up.

I'd put the loop in the advice if I were you, rather than using
recursion in this way, and then guard the advice so it doesn't run
more than once in an execution stack.  This pointcut will avoid
running the advice more than once in a recursive call:

       @After("execution(@com.xxxx.util.annotation.RunMultiple *
*.*(..)) && !within(RunMultipleAspect) && !cflow(adviceexecution())")

The last part says 'do not run this advice if we are in the control
flow of some already running advice'.

But basically it is as you thought,  you are recursing because advice
is calling an advised method.

cheers,
Andy.

2008/7/2 jacknjill111 <jacknjill111@...>:

>
> Environment:
> AspectJ 1.6.0
> JDK 6u10
>
> Background info:
> I've coded an Aspect that would run a particular method a specific number of
> times. I've created an annotation that can be used to annotate any method
> that you want to run multiple times
>
> RunMultipleAspectTestApp is the driver class. When I set the
> RunMultiple.counter to something less than 900, it works great.
> But when I raise it to 1000 or more, I get a java.lang.StackOverflow error.
> I googled and saw that StackOverFlow error occur
> due to infinite recursion as noted in this document:
> http://www.eclipse.org/aspectj/doc/released/faq.html#q:infiniterecursion
> Do I have my pointcut defined incorrectly? Could someone please help me with
> the pointcut definition for the "repeat" advice?
>
>
> ************ RunMultipleAspectTestApp.java - START **************
>
> package com.xxxx.aop.util;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
>
> import com.xxxx.util.annotation.RunMultiple;
>
> public class RunMultipleAspectTestApp {
>
>        private final Log logger = LogFactory.getLog(getClass());
>
>        public static void main(String[] args) {
>                RunMultipleAspectTestApp rmata = new RunMultipleAspectTestApp();
>
>                rmata.runMe();
>                rmata.runMe("Hello", "World");
>        }
>
>        @RunMultiple
>        public void runMe() {
>                if (logger.isDebugEnabled()) {
>                        logger.debug("Hello Jack");
>                }
>        }
>
>        @RunMultiple(counter = 950)
>        public void runMe(String greeting, String name) {
>                if (logger.isDebugEnabled()) {
>                        logger.debug(greeting + " " + name);
>                }
>        }
> }
>
> ************ RunMultipleAspectTestApp.java - END **************
>
>
> ************ RunMultiple.java - START **************
>
> package com.xxxx.util.annotation;
>
> import java.lang.annotation.ElementType;
> import java.lang.annotation.Retention;
> import java.lang.annotation.RetentionPolicy;
> import java.lang.annotation.Target;
>
> @Retention(RetentionPolicy.RUNTIME)
> @Target(ElementType.METHOD)
> public @interface RunMultiple {
>        /**
>         * Number of times a method should be invoked
>         */
>        int counter() default 1;
> }
>
> ************ RunMultiple.java - END**************
>
> The RunMultipleAspect has a repeat (After) advice which is called on any
> method annotated with the RunMultiple annotation. RunMultipleAspect
> also intercepts object construction (AfterReturning) and caches the object
> that is created so it can reuse the object in the repeat advice.
> The repeat advice looks up the RunMultiple.counter value and then invokes
> the object method if 'RunMultipleAspect.count < RunMultiple.counter'
>
> ************ RunMultipleAspect.java - START **************
>
> package com.xxxx.aop.util;
>
> import java.lang.reflect.InvocationTargetException;
> import java.lang.reflect.Method;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.aspectj.lang.JoinPoint;
> import org.aspectj.lang.ProceedingJoinPoint;
> import org.aspectj.lang.annotation.After;
> import org.aspectj.lang.annotation.AfterReturning;
> import org.aspectj.lang.annotation.Aspect;
> import org.aspectj.lang.reflect.CodeSignature;
> import org.aspectj.lang.reflect.MethodSignature;
>
> import com.xxxx.util.annotation.RunMultiple;
>
> /**
>  * Aspect to replace the following construct
>  *
>  *  ...
>  *  int counter = 10000;
>  *  for (int i=0; i < counter; i++) {
>  *    greet();
>  *  }
>  *
>  *   public void greet() {
>  *      ...
>  *      ...
>  *   }
>  *
>  *  with this construct:
>  *
>  *  @RunMultiple(counter=1000)
>  *  public void greet() {
>  *     ...
>  *  }
>  *
>  */
>
> @Aspect
> public class RunMultipleAspect {
>
>        private final Log logger = LogFactory.getLog(getClass());
>
>        private int count = 0; // keeps track of how many times a method has been
> executed
>        private String methodName; // keeps track of method name since we could
> have multiple (overloaded) methods annotated
>        private Object obj; // object instance that was created once
>
>        @After("execution(@com.xxxx.util.annotation.RunMultiple * *.*(..)) &&
> !within(RunMultipleAspect)")
>        public void repeat(JoinPoint jp) throws ClassNotFoundException,
>                        IllegalArgumentException, IllegalAccessException,
>                        InvocationTargetException, InstantiationException {
>                Method method = ((MethodSignature) jp.getSignature()).getMethod();
>
>                printArguments(jp);
>
>                // doing this to store the current method name
>                String tempMethodName = jp.getTarget().getClass().getName() + "."
>                                + method.getName() + this.getArgumentTypes(jp);
>                if (!tempMethodName.equals(methodName)) {
>                        this.methodName = jp.getTarget().getClass().getName() + "."
>                                        + method.getName() + this.getArgumentTypes(jp);
>                        this.count = 0;
>                }
>
>                RunMultiple rmAnnotation = method.getAnnotation(RunMultiple.class);
>                if (logger.isTraceEnabled()) {
>                        logger.trace("rmAnnotation.toString(): " + rmAnnotation.toString());
>                }
>
>                if (logger.isTraceEnabled()) {
>                        logger.trace("count: " + count + " :: " + rmAnnotation.counter());
>                }
>                if (++count < rmAnnotation.counter()) {
>                        if (logger.isTraceEnabled()) {
>                                logger.trace("using object " + obj.hashCode());
>                                logger.trace(obj.getClass().getName() + "." + method.getName());
>                        }
>                        method.invoke(obj, jp.getArgs());
>                }
>        }
>
>  /**
>   * Stores the object instance in 'obj' the first time it is created so I
> can
>   * call methods on that instance
>   */
>        @AfterReturning("execution(*.new(..)) && !within(RunMultipleAspect)")
>        public void setObjectAtConstruction(JoinPoint jp) {
>                if (logger.isTraceEnabled()) {
>                        logger.trace("jp.getTarget(): " + jp.getTarget().hashCode()
>                                        + ", jp.getThis(): " + jp.getThis().hashCode());
>                }
>
>                if (obj == null) {
>                        this.obj = jp.getTarget();
>                        if (logger.isTraceEnabled()) {
>                                logger.trace("creating object: " + obj.hashCode());
>                        }
>                } else {
>                        if (logger.isTraceEnabled()) {
>                                logger.trace("object created earlier: " + obj.hashCode());
>                        }
>                }
>        }
>
>
>        private String getArgumentTypes(JoinPoint jp) {
>                Class<?>[] argTypes = ((CodeSignature) jp.getSignature())
>                                .getParameterTypes();
>
>                if (argTypes != null && argTypes.length > 0) {
>                        StringBuilder sb = new StringBuilder("(");
>                        for (int ar = 0; ar < argTypes.length; ar++) {
>                                sb.append(argTypes[ar].getName());
>                                if (ar < argTypes.length - 1) {
>                                        sb.append(",");
>                                }
>                        }
>                        sb.append(")");
>
>                        return sb.toString();
>                }
>
>                return "";
>        }
>
>        private void printArguments(JoinPoint jp) {
>                Object[] args = jp.getArgs();
>                String[] argNames = ((CodeSignature) jp.getSignature())
>                                .getParameterNames();
>                Class<?>[] argTypes = ((CodeSignature) jp.getSignature())
>                                .getParameterTypes();
>
>                for (int i = 0; i < args.length; i++) {
>                        if (logger.isTraceEnabled()) {
>                                logger.trace(argTypes[i].getName() + "." + argNames[i] + "="
>                                                + args[i]);
>                        }
>                }
>
>        }
>
>
> }
>
> ************ RunMultipleAspect.java - END **************
>
> My aop.xml looks like this:
>
> <aspects>
>
>        <aspect name="com.xxxx.aop.util.RunMultipleAspect" />
>
>        <weaver options="-verbose -showWeaveInfo -debug">
>                <include within="com.xxxx.aop.util..*" />
>                <exclude within="com.xxxx.aop.util.RunMultipleAspect" />
>        </weaver>
>
> </aspects>
>
> ******************** Output/Error log: **************************
>
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 929 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> 2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.greeting=Hello
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.name=World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 930 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> 2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.greeting=Hello
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.name=World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 931 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> 2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.greeting=Hello
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.name=World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 932 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> Exception in thread "main" java.lang.reflect.InvocationTargetException
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.main(RunMultipleAspectTestApp.java:16)
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        ... 7 more
> .......
> .......
> .......
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        ... 1012 more
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        ... 1017 more
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> ........
> ........
> ........
> Caused by: java.lang.reflect.InvocationTargetException
>        ... 1024 more
> Caused by: java.lang.reflect.InvocationTargetException
>        ... 1024 more
> Caused by: java.lang.StackOverflowError
>        at java.text.DecimalFormat.subformat(Unknown Source)
>        at java.text.DecimalFormat.format(Unknown Source)
>        at java.text.DecimalFormat.format(Unknown Source)
>        at java.text.SimpleDateFormat.zeroPaddingNumber(Unknown Source)
>        at java.text.SimpleDateFormat.subFormat(Unknown Source)
>        at java.text.SimpleDateFormat.format(Unknown Source)
>        at java.text.SimpleDateFormat.format(Unknown Source)
>        at java.text.DateFormat.format(Unknown Source)
>        at org.apache.commons.logging.impl.SimpleLog.log(SimpleLog.java:294)
>        at org.apache.commons.logging.impl.SimpleLog.trace(SimpleLog.java:416)
>        at
> com.xxxx.aop.util.RunMultipleAspect.printArguments(RunMultipleAspect.java:175)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:115)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>
>
>
>
> Any help is greatly appreciated.
> --
> View this message in context: http://www.nabble.com/StackOverflow-error-tp18247723p18247723.html
> Sent from the AspectJ - users mailing list archive at Nabble.com.
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@...
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: StackOverflow error

by jacknjill111 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andy,
Your advice :) worked like a charm!

Showing only relevant changes to code (RunMultipleAspect.java)

@After("execution(@com.xxxx.util.annotation.RunMultiple * *.*(..)) && !within(RunMultipleAspect) && !cflow(adviceexecution())")
public void repeat(JoinPoint jp) throws ClassNotFoundException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
        ....
        ....
         //        if (++count < rmAnnotation.counter()) {
//            if (logger.isTraceEnabled()) {
//                logger.trace("using object " + obj.hashCode());
//                logger.trace(obj.getClass().getName() + "." + method.getName() + ", count: " + count);
//            }
//            method.invoke(obj, jp.getArgs());
//        }
        for (int i=0; i<rmAnnotation.counter(); i++) {
            method.invoke(obj, jp.getArgs());
        }
    }

Another approach:
Your suggestion also made me realise that I could rewrite the pointcut to pick out the method call join-point rather than the method execution and then I would not need the !cflow(adviceexecution()). Like below:

@After("call(@com.xxxx.util.annotation.RunMultiple * *.*(..)) && !within(RunMultipleAspect)")
public void repeat(JoinPoint jp) throws ClassNotFoundException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
        ....
        ....
         //        if (++count < rmAnnotation.counter()) {
//            if (logger.isTraceEnabled()) {
//                logger.trace("using object " + obj.hashCode());
//                logger.trace(obj.getClass().getName() + "." + method.getName() + ", count: " + count);
//            }
//            method.invoke(obj, jp.getArgs());
//        }
        for (int i=0; i<rmAnnotation.counter(); i++) {
            method.invoke(obj, jp.getArgs());
        }
    }

Question:
While looking at the output I see the following line:

[AppClassLoader@df6ccd] debug weaving 'com.xxxx.aop.util.RunMultipleAspect'

In my aop.xml, I did put an exclude for RunMultipleAspect:

    <weaver options="-verbose -showWeaveInfo -debug">
    <!-- <weaver> -->
        <include within="com.xxxx.aop.util..*" />
        <exclude within="com.xxxx.aop.util.RunMultipleAspect" />
    </weaver>

So why does aspectjweaver try to weave RunMultipleAspect? Is it because I am telling the weaver to include all files in the "com.xxxx.aop.util" package. From the docs: http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html#weaver-options

"The set of types to be woven are those types matched by at least one weaver include element and not matched by any weaver exclude element. If there are no weaver include statements then all non-excluded types are included."

Thanks for your time and assistance, Andy!

R




On Thu, Jul 3, 2008 at 10:59 AM, Andy Clement <andrew.clement@...> wrote:
Hello,

You have advised runMe() to execute your advice:

      @RunMultiple(counter = 1000)
      public void runMe(String greeting, String name) {
              if (logger.isDebugEnabled()) {
                      logger.debug(greeting + " " + name);
              }
      }

Your advice then says if count is less than the annotation value
counter, call runMe().  This will invoke the advised version of
runMe(greeting,name).  And then we will come back into the aspect and
do it again, and so on and so on. Did you really want to call the
advised version of runMe() - I guess you did from the aspect
structure.  This recursion only stops when count is finally greater
than counter.  The JVM can handle a certain level of recursion before
it just gives up and throws StackOverflow - and your 1000 number seems
to be the point where it is giving up.

I'd put the loop in the advice if I were you, rather than using
recursion in this way, and then guard the advice so it doesn't run
more than once in an execution stack.  This pointcut will avoid
running the advice more than once in a recursive call:

      @After("execution(@com.xxxx.util.annotation.RunMultiple *
*.*(..)) && !within(RunMultipleAspect) && !cflow(adviceexecution())")

The last part says 'do not run this advice if we are in the control
flow of some already running advice'.

But basically it is as you thought,  you are recursing because advice
is calling an advised method.

cheers,
Andy.

2008/7/2 jacknjill111 <jacknjill111@...>:
>
> Environment:
> AspectJ 1.6.0
> JDK 6u10
>
> Background info:
> I've coded an Aspect that would run a particular method a specific number of
> times. I've created an annotation that can be used to annotate any method
> that you want to run multiple times
>
> RunMultipleAspectTestApp is the driver class. When I set the
> RunMultiple.counter to something less than 900, it works great.
> But when I raise it to 1000 or more, I get a java.lang.StackOverflow error.
> I googled and saw that StackOverFlow error occur
> due to infinite recursion as noted in this document:
> http://www.eclipse.org/aspectj/doc/released/faq.html#q:infiniterecursion
> Do I have my pointcut defined incorrectly? Could someone please help me with
> the pointcut definition for the "repeat" advice?
>
>
> ************ RunMultipleAspectTestApp.java - START **************
>
> package com.xxxx.aop.util;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
>
> import com.xxxx.util.annotation.RunMultiple;
>
> public class RunMultipleAspectTestApp {
>
>        private final Log logger = LogFactory.getLog(getClass());
>
>        public static void main(String[] args) {
>                RunMultipleAspectTestApp rmata = new RunMultipleAspectTestApp();
>
>                rmata.runMe();
>                rmata.runMe("Hello", "World");
>        }
>
>        @RunMultiple
>        public void runMe() {
>                if (logger.isDebugEnabled()) {
>                        logger.debug("Hello Jack");
>                }
>        }
>
>        @RunMultiple(counter = 950)
>        public void runMe(String greeting, String name) {
>                if (logger.isDebugEnabled()) {
>                        logger.debug(greeting + " " + name);
>                }
>        }
> }
>
> ************ RunMultipleAspectTestApp.java - END **************
>
>
> ************ RunMultiple.java - START **************
>
> package com.xxxx.util.annotation;
>
> import java.lang.annotation.ElementType;
> import java.lang.annotation.Retention;
> import java.lang.annotation.RetentionPolicy;
> import java.lang.annotation.Target;
>
> @Retention(RetentionPolicy.RUNTIME)
> @Target(ElementType.METHOD)
> public @interface RunMultiple {
>        /**
>         * Number of times a method should be invoked
>         */
>        int counter() default 1;
> }
>
> ************ RunMultiple.java - END**************
>
> The RunMultipleAspect has a repeat (After) advice which is called on any
> method annotated with the RunMultiple annotation. RunMultipleAspect
> also intercepts object construction (AfterReturning) and caches the object
> that is created so it can reuse the object in the repeat advice.
> The repeat advice looks up the RunMultiple.counter value and then invokes
> the object method if 'RunMultipleAspect.count < RunMultiple.counter'
>
> ************ RunMultipleAspect.java - START **************
>
> package com.xxxx.aop.util;
>
> import java.lang.reflect.InvocationTargetException;
> import java.lang.reflect.Method;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.aspectj.lang.JoinPoint;
> import org.aspectj.lang.ProceedingJoinPoint;
> import org.aspectj.lang.annotation.After;
> import org.aspectj.lang.annotation.AfterReturning;
> import org.aspectj.lang.annotation.Aspect;
> import org.aspectj.lang.reflect.CodeSignature;
> import org.aspectj.lang.reflect.MethodSignature;
>
> import com.xxxx.util.annotation.RunMultiple;
>
> /**
>  * Aspect to replace the following construct
>  *
>  *  ...
>  *  int counter = 10000;
>  *  for (int i=0; i < counter; i++) {
>  *    greet();
>  *  }
>  *
>  *   public void greet() {
>  *      ...
>  *      ...
>  *   }
>  *
>  *  with this construct:
>  *
>  *  @RunMultiple(counter=1000)
>  *  public void greet() {
>  *     ...
>  *  }
>  *
>  */
>
> @Aspect
> public class RunMultipleAspect {
>
>        private final Log logger = LogFactory.getLog(getClass());
>
>        private int count = 0; // keeps track of how many times a method has been
> executed
>        private String methodName; // keeps track of method name since we could
> have multiple (overloaded) methods annotated
>        private Object obj; // object instance that was created once
>
>        @After("execution(@com.xxxx.util.annotation.RunMultiple * *.*(..)) &&
> !within(RunMultipleAspect)")
>        public void repeat(JoinPoint jp) throws ClassNotFoundException,
>                        IllegalArgumentException, IllegalAccessException,
>                        InvocationTargetException, InstantiationException {
>                Method method = ((MethodSignature) jp.getSignature()).getMethod();
>
>                printArguments(jp);
>
>                // doing this to store the current method name
>                String tempMethodName = jp.getTarget().getClass().getName() + "."
>                                + method.getName() + this.getArgumentTypes(jp);
>                if (!tempMethodName.equals(methodName)) {
>                        this.methodName = jp.getTarget().getClass().getName() + "."
>                                        + method.getName() + this.getArgumentTypes(jp);
>                        this.count = 0;
>                }
>
>                RunMultiple rmAnnotation = method.getAnnotation(RunMultiple.class);
>                if (logger.isTraceEnabled()) {
>                        logger.trace("rmAnnotation.toString(): " + rmAnnotation.toString());
>                }
>
>                if (logger.isTraceEnabled()) {
>                        logger.trace("count: " + count + " :: " + rmAnnotation.counter());
>                }
>                if (++count < rmAnnotation.counter()) {
>                        if (logger.isTraceEnabled()) {
>                                logger.trace("using object " + obj.hashCode());
>                                logger.trace(obj.getClass().getName() + "." + method.getName());
>                        }
>                        method.invoke(obj, jp.getArgs());
>                }
>        }
>
>  /**
>   * Stores the object instance in 'obj' the first time it is created so I
> can
>   * call methods on that instance
>   */
>        @AfterReturning("execution(*.new(..)) && !within(RunMultipleAspect)")
>        public void setObjectAtConstruction(JoinPoint jp) {
>                if (logger.isTraceEnabled()) {
>                        logger.trace("jp.getTarget(): " + jp.getTarget().hashCode()
>                                        + ", jp.getThis(): " + jp.getThis().hashCode());
>                }
>
>                if (obj == null) {
>                        this.obj = jp.getTarget();
>                        if (logger.isTraceEnabled()) {
>                                logger.trace("creating object: " + obj.hashCode());
>                        }
>                } else {
>                        if (logger.isTraceEnabled()) {
>                                logger.trace("object created earlier: " + obj.hashCode());
>                        }
>                }
>        }
>
>
>        private String getArgumentTypes(JoinPoint jp) {
>                Class<?>[] argTypes = ((CodeSignature) jp.getSignature())
>                                .getParameterTypes();
>
>                if (argTypes != null && argTypes.length > 0) {
>                        StringBuilder sb = new StringBuilder("(");
>                        for (int ar = 0; ar < argTypes.length; ar++) {
>                                sb.append(argTypes[ar].getName());
>                                if (ar < argTypes.length - 1) {
>                                        sb.append(",");
>                                }
>                        }
>                        sb.append(")");
>
>                        return sb.toString();
>                }
>
>                return "";
>        }
>
>        private void printArguments(JoinPoint jp) {
>                Object[] args = jp.getArgs();
>                String[] argNames = ((CodeSignature) jp.getSignature())
>                                .getParameterNames();
>                Class<?>[] argTypes = ((CodeSignature) jp.getSignature())
>                                .getParameterTypes();
>
>                for (int i = 0; i < args.length; i++) {
>                        if (logger.isTraceEnabled()) {
>                                logger.trace(argTypes[i].getName() + "." + argNames[i] + "="
>                                                + args[i]);
>                        }
>                }
>
>        }
>
>
> }
>
> ************ RunMultipleAspect.java - END **************
>
> My aop.xml looks like this:
>
> <aspects>
>
>        <aspect name="com.xxxx.aop.util.RunMultipleAspect" />
>
>        <weaver options="-verbose -showWeaveInfo -debug">
>                <include within="com.xxxx.aop.util..*" />
>                <exclude within="com.xxxx.aop.util.RunMultipleAspect" />
>        </weaver>
>
> </aspects>
>
> ******************** Output/Error log: **************************
>
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 929 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> 2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.greeting=Hello
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.name=World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 930 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> 2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.greeting=Hello
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.name=World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 931 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> 2008/07/02 16:30:32:281 CDT [DEBUG] RunMultipleAspectTestApp - Hello World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.greeting=Hello
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> java.lang.String.name=World
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> rmAnnotation.toString(): @com.xxxx.util.annotation.RunMultiple(counter=950)
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - count: 932 :: 950
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect - using object
> 14779369
> 2008/07/02 16:30:32:281 CDT [TRACE] RunMultipleAspect -
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe
> Exception in thread "main" java.lang.reflect.InvocationTargetException
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.main(RunMultipleAspectTestApp.java:16)
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        ... 7 more
> .......
> .......
> .......
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        ... 1012 more
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        ... 1017 more
> Caused by: java.lang.reflect.InvocationTargetException
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> ........
> ........
> ........
> Caused by: java.lang.reflect.InvocationTargetException
>        ... 1024 more
> Caused by: java.lang.reflect.InvocationTargetException
>        ... 1024 more
> Caused by: java.lang.StackOverflowError
>        at java.text.DecimalFormat.subformat(Unknown Source)
>        at java.text.DecimalFormat.format(Unknown Source)
>        at java.text.DecimalFormat.format(Unknown Source)
>        at java.text.SimpleDateFormat.zeroPaddingNumber(Unknown Source)
>        at java.text.SimpleDateFormat.subFormat(Unknown Source)
>        at java.text.SimpleDateFormat.format(Unknown Source)
>        at java.text.SimpleDateFormat.format(Unknown Source)
>        at java.text.DateFormat.format(Unknown Source)
>        at org.apache.commons.logging.impl.SimpleLog.log(SimpleLog.java:294)
>        at org.apache.commons.logging.impl.SimpleLog.trace(SimpleLog.java:416)
>        at
> com.xxxx.aop.util.RunMultipleAspect.printArguments(RunMultipleAspect.java:175)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:115)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>        at
> com.xxxx.aop.util.RunMultipleAspectTestApp.runMe(RunMultipleAspectTestApp.java:52)
>        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>        at java.lang.reflect.Method.invoke(Unknown Source)
>        at com.xxxx.aop.util.RunMultipleAspect.repeat(RunMultipleAspect.java:142)
>
>
>
>
> Any help is greatly appreciated.
> --
> View this message in context: http://www.nabble.com/StackOverflow-error-tp18247723p18247723.html
> Sent from the AspectJ - users mailing list archive at Nabble.com.
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@...
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users


_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: StackOverflow error

by Andy Clement :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/7/3 Jack Jill <jacknjill111@...>:

> Question:
> While looking at the output I see the following line:
>
> [AppClassLoader@df6ccd] debug weaving 'com.xxxx.aop.util.RunMultipleAspect'
>
> In my aop.xml, I did put an exclude for RunMultipleAspect:
>
>     <weaver options="-verbose -showWeaveInfo -debug">
>     <!-- <weaver> -->
>         <include within="com.xxxx.aop.util..*" />
>         <exclude within="com.xxxx.aop.util.RunMultipleAspect" />
>     </weaver>
>
> So why does aspectjweaver try to weave RunMultipleAspect? Is it because I am
> telling the weaver to include all files in the "com.xxxx.aop.util" package.

Good question.  The reason is that RunMultipleAspect is an annotation
style aspect.  We cannot guarantee that annotation style aspects have
been compiled with ajc - someone may have used javac to compile them.
Because of this we need to ensure they have the aspectOf() and
hasAspect() methods put into them (ajc would have done it, but javac
would not).  That message indicates the aspect is being woven *but* it
is only going to get the aspectOf() and hasAspect() methods added (or
at least that is all that *should* happen).

I think that message could be improved to indicate this...

Andy.
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: StackOverflow error

by Holger Hoffstätte-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jack Jill wrote:

> Andy,
> Your advice :) worked like a charm!
>
> Showing only relevant changes to code (RunMultipleAspect.java)
>
> *@After("execution(@com.xxxx.util.annotation.RunMultiple * *.*(..)) &&
> !within(RunMultipleAspect) && !cflow(adviceexecution())")*
> public void repeat(JoinPoint jp) throws ClassNotFoundException,
>             IllegalArgumentException, IllegalAccessException,
>             InvocationTargetException, InstantiationException {
>         ....
>         ....
> *         //        if (++count < rmAnnotation.counter()) {
[..snip..]

Hey :)

I quickly read through your example and was wondering if you couldn't just
use "around" to call proceed() n times in your loop. This should work the
same but without all the hand-made reflection stuff and (as far as I can
see?) no need for cflowbelow, no stack overflow etc. Would this work too?

Holger
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: StackOverflow error

by jacknjill111 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Cool. Thanks for that piece of information, Andy.

On Thu, Jul 3, 2008 at 2:15 PM, Andy Clement <andrew.clement@...> wrote:
2008/7/3 Jack Jill <jacknjill111@...>:
> Question:
> While looking at the output I see the following line:
>
> [AppClassLoader@df6ccd] debug weaving 'com.xxxx.aop.util.RunMultipleAspect'
>
> In my aop.xml, I did put an exclude for RunMultipleAspect:
>
>     <weaver options="-verbose -showWeaveInfo -debug">
>     <!-- <weaver> -->
>         <include within="com.xxxx.aop.util..*" />
>         <exclude within="com.xxxx.aop.util.RunMultipleAspect" />
>     </weaver>
>
> So why does aspectjweaver try to weave RunMultipleAspect? Is it because I am
> telling the weaver to include all files in the "com.xxxx.aop.util" package.

Good question.  The reason is that RunMultipleAspect is an annotation
style aspect.  We cannot guarantee that annotation style aspects have
been compiled with ajc - someone may have used javac to compile them.
Because of this we need to ensure they have the aspectOf() and
hasAspect() methods put into them (ajc would have done it, but javac
would not).  That message indicates the aspect is being woven *but* it
is only going to get the aspectOf() and hasAspect() methods added (or
at least that is all that *should* happen).

I think that message could be improved to indicate this...

Andy.
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users


_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: StackOverflow error

by jacknjill111 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Holger,
You are right! I could have done it far easier using around advice:

    @Around("call(@com.plexibus.util.annotation.RunMultiple * *.*(..))")
    public Object tryAgain(ProceedingJoinPoint jp) throws Throwable {
        Method method = ((MethodSignature) jp.getSignature()).getMethod();

        RunMultiple rmAnnotation = method.getAnnotation(RunMultiple.class);

        Throwable err = null;

        for (int i = 0; i < rmAnnotation.counter(); i++) {

            if (logger.isTraceEnabled()) {
                logger.trace("i: " + i);
            }
            try {
                method.invoke(obj, jp.getArgs());
            } catch (Throwable t) {
                // do something with err...might need to resubmit job...
                throw err;
            }
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Finished Around advice");
        }
       
        return jp.proceed();
    }

This eliminates all other methods (the other pointcuts and advices included) in the RunMultipleAspect!

Thanks for refactoring suggestion, Holger :) Geez, now I feel like an idiot!

R

On Thu, Jul 3, 2008 at 2:16 PM, Holger Hoffstätte <holger@...> wrote:
Jack Jill wrote:
Andy,
Your advice :) worked like a charm!

Showing only relevant changes to code (RunMultipleAspect.java)

*@After("execution(@com.xxxx.util.annotation.RunMultiple * *.*(..)) && !within(RunMultipleAspect) && !cflow(adviceexecution())")*
public void repeat(JoinPoint jp) throws ClassNotFoundException,
           IllegalArgumentException, IllegalAccessException,
           InvocationTargetException, InstantiationException {
       ....
       ....
*         //        if (++count < rmAnnotation.counter()) {
[..snip..]

Hey :)

I quickly read through your example and was wondering if you couldn't just use "around" to call proceed() n times in your loop. This should work the same but without all the hand-made reflection stuff and (as far as I can see?) no need for cflowbelow, no stack overflow etc. Would this work too?

Holger

_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users


_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users