--- /dev/null
+package ma;
+
+import ma.aspect1.Annotation1;
+import ma.aspect2.Annotation2;
+import ma.aspect3.Annotation3;
+
+public class Main {
+
+ public static class Dummy {
+
+ private int counter = 0;
+
+ @Annotation1
+ @Annotation2
+ @Annotation3
+ public int retryTranslateAndTimeLimited() {
+ System.out.println("Method call");
+ if (counter++ == 0) {
+ throw new IllegalStateException();
+ } else {
+ return 1;
+ }
+ }
+
+ }
+
+ public static void main(String[] args) {
+ new Dummy().retryTranslateAndTimeLimited();
+ }
+
+}
--- /dev/null
+package ma;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.DeclarePrecedence;
+
+@Aspect
+@DeclarePrecedence("ma.aspect1.Aspect1, "
+ + "ma.aspect2.Aspect2, "
+ + "ma.aspect3.Aspect3")
+class Precedence {
+
+}
--- /dev/null
+package ma.aspect1;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation1 {
+
+}
--- /dev/null
+package ma.aspect1;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+
+@Aspect
+public class Aspect1 {
+
+ @Around("(execution(@ma.aspect1.Annotation1 * *(..)) || execution(@ma.aspect1.Annotation1 *.new(..)))")
+ public Object inRetryAspect(ProceedingJoinPoint pjp) throws Throwable {
+
+ InternalClass ic = new InternalClass();
+
+ System.out.println(">In Aspect1");
+
+ try {
+ pjp.proceed();
+ } catch (Exception ignored) {
+
+ }
+
+ System.out.println("=In Aspect1");
+ try {
+ return pjp.proceed();
+ } finally {
+ System.out.println("<In Aspect1");
+ }
+
+ }
+
+ private static class InternalClass {
+ }
+
+}
--- /dev/null
+package ma.aspect2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation2 {
+
+}
--- /dev/null
+package ma.aspect2;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+@Aspect
+public class Aspect2 {
+
+ @Around("(execution(@ma.aspect2.Annotation2 * *(..)) || execution(@ma.aspect2.Annotation2 *.new(..)))")
+ public Object inExceptionTranslatorAspect(ProceedingJoinPoint pjp) throws Throwable {
+
+ System.out.println(">In Aspect2");
+
+ try {
+ Object returnedObject = pjp.proceed();
+ System.out.println("<In Aspect2");
+ return returnedObject;
+ } catch (Throwable thrownThrowable) {
+ System.out.println("<In Aspect2");
+ throw thrownThrowable;
+ }
+
+ }
+
+}
--- /dev/null
+package ma.aspect3;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation3 {
+}
--- /dev/null
+package ma.aspect3;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+@Aspect
+public class Aspect3 {
+
+ @Around("(execution(@ma.aspect3.Annotation3 * *(..)) || execution(@ma.aspect3.Annotation3 *.new(..)))")
+ public Object inTimeLimiterAspect(ProceedingJoinPoint pjp) throws Throwable {
+
+ InnerClass2 c = new InnerClass2();
+
+ System.out.println(">In Aspect3");
+ try {
+ Object returnedObject = pjp.proceed();
+ System.out.println("<In Aspect3");
+ return returnedObject;
+ } catch (Exception e) {
+ System.out.println("<In Aspect3");
+ throw e;
+ }
+
+ }
+
+ private static class InnerClass2 {
+
+ }
+}
--- /dev/null
+package ma2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation1 {
+
+}
--- /dev/null
+package ma2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Annotation2 {
+
+}
--- /dev/null
+package ma2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation3 {
+}
--- /dev/null
+package ma2;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+
+public aspect Aspect1 {
+
+ Object around(): (execution(@Annotation1 * *(..)) || execution(@Annotation1 *.new(..))) {
+
+ InternalClass ic = new InternalClass();
+
+ System.out.println(">In Aspect1");
+
+ try {
+ proceed();
+ } catch (Exception ignored) {
+
+ }
+
+ System.out.println("=In Aspect1");
+ try {
+ return proceed();
+ } finally {
+ System.out.println("<In Aspect1");
+ }
+
+ }
+
+ private static class InternalClass {
+ }
+
+}
--- /dev/null
+package ma2;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+
+public aspect Aspect2 {
+
+ Object around(): execution(@Annotation2 * *(..)) || execution(@Annotation2 *.new(..)) {
+/*
+ @Around("(execution(@ma.aspect2.Annotation2 * *(..)) || execution(@ma.aspect2.Annotation2 *.new(..)))")
+ public Object inExceptionTranslatorAspect(ProceedingJoinPoint pjp) throws Throwable {
+*/
+
+ System.out.println(">In Aspect2");
+
+ try {
+ Object returnedObject = proceed();
+ System.out.println("<In Aspect2");
+ return returnedObject;
+ } catch (Throwable thrownThrowable) {
+ System.out.println("<In Aspect2");
+ throw new RuntimeException(thrownThrowable);
+ }
+
+ }
+
+}
--- /dev/null
+package ma2;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+public aspect Aspect3 {
+
+ Object around(): execution(@Annotation3 * *(..)) || execution(@Annotation3 *.new(..)) {
+/*
+ @Around("(execution(@ma.aspect3.Annotation3 * *(..)) || execution(@ma.aspect3.Annotation3 *.new(..)))")
+ public Object inTimeLimiterAspect(ProceedingJoinPoint pjp) throws Throwable {
+*/
+
+ InnerClass2 c = new InnerClass2();
+
+ System.out.println(">In Aspect3");
+ try {
+ Object returnedObject =proceed();
+ System.out.println("<In Aspect3");
+ return returnedObject;
+ } catch (Exception e) {
+ System.out.println("<In Aspect3");
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class InnerClass2 {
+
+ }
+}
--- /dev/null
+package ma2;
+
+public class Main {
+
+ public static class Dummy {
+
+ private int counter = 0;
+
+ @Annotation1
+ @Annotation2
+ @Annotation3
+ public int retryTranslateAndTimeLimited() {
+ System.out.println("Method call");
+ if (counter++ == 0) {
+ throw new IllegalStateException();
+ } else {
+ return 1;
+ }
+ }
+
+ }
+
+ public static void main(String[] args) {
+ new Dummy().retryTranslateAndTimeLimited();
+ }
+
+}
--- /dev/null
+package ma2;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.DeclarePrecedence;
+
+@Aspect
+@DeclarePrecedence("ma2.Aspect1, "
+ + "ma2.Aspect2, "
+ + "ma2.Aspect3")
+class Precedence {
+
+}
--- /dev/null
+package ma.aspect1;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation1 {
+
+}
--- /dev/null
+package ma.aspect1;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+
+public aspect Aspect1 {
+
+ Object around(): (execution(@Annotation1 * *(..)) || execution(@Annotation1 *.new(..))) {
+
+ InternalClass ic = new InternalClass();
+
+ System.out.println(">In Aspect1");
+
+ try {
+ proceed();
+ } catch (Exception ignored) {
+
+ }
+
+ System.out.println("=In Aspect1");
+ try {
+ return proceed();
+ } finally {
+ System.out.println("<In Aspect1");
+ }
+
+ }
+
+ private static class InternalClass {
+ }
+
+}
--- /dev/null
+package ma.aspect2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation2 {
+
+}
--- /dev/null
+package ma.aspect2;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+@Aspect
+public class Aspect2 {
+
+ @Around("(execution(@ma.aspect2.Annotation2 * *(..)) || execution(@ma.aspect2.Annotation2 *.new(..)))")
+ public Object inExceptionTranslatorAspect(ProceedingJoinPoint pjp) throws Throwable {
+
+ System.out.println(">In Aspect2");
+
+ try {
+ Object returnedObject = pjp.proceed();
+ System.out.println("<In Aspect2");
+ return returnedObject;
+ } catch (Throwable thrownThrowable) {
+ System.out.println("<In Aspect2");
+ throw thrownThrowable;
+ }
+
+ }
+
+}
--- /dev/null
+package ma.aspect3;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Annotation3 {
+}
--- /dev/null
+package ma.aspect3;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+@Aspect
+public class Aspect3 {
+
+ @Around("(execution(@ma.aspect3.Annotation3 * *(..)) || execution(@ma.aspect3.Annotation3 *.new(..)))")
+ public Object inTimeLimiterAspect(ProceedingJoinPoint pjp) throws Throwable {
+
+ InnerClass2 c = new InnerClass2();
+
+ System.out.println(">In Aspect3");
+ try {
+ Object returnedObject = pjp.proceed();
+ System.out.println("<In Aspect3");
+ return returnedObject;
+ } catch (Exception e) {
+ System.out.println("<In Aspect3");
+ throw e;
+ }
+
+ }
+
+ private static class InnerClass2 {
+
+ }
+}