Community
Participate
Working Groups
I'm getting the below exception whenever the @Around is uncommented: package com.foliofn.infra.logging; import java.lang.reflect.Field; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.NDC; import org.apache.log4j.spi.LoggingEvent; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; @Aspect public class ExceptionMessageNdcAdderC { static final String SEPERATOR = " - "; private Logger log = Logger.getLogger(getClass()); @Pointcut("call(Throwable+.new(String, ..)) && this(caller) && args(exceptionMessage) && if()") public static boolean exceptionInitializer(Object caller, String exceptionMessage) { return isNdcEmpty(); } // Comment out just the next line and the error does not occur. @Around("exceptionInitializer(caller, exceptionMessage)") public Object annotateException(ProceedingJoinPoint jp, Object caller, String exceptionMessage) { // return jp.proceed(new Object[]{caller, ndcAnnotateMessage(exceptionMessage)}); return null; } private static boolean isNdcEmpty() { return NDC.getDepth() == 0; } private String ndcAnnotateMessage(String message) { return formatNdcAnnotatedMessage(getNcdValue(), message); } private String getNcdValue() { LoggingEvent logEvent = new LoggingEvent("anything", log, Level.INFO, "anything", null); return logEvent.getNDC(); } static String formatNdcAnnotatedMessage(String ndcValue, String message) { return ndcValue + SEPERATOR + message; } } ------ org.aspectj.weaver.BCException at org.aspectj.weaver.bcel.BcelRenderer.visit(BcelRenderer.java:237) at org.aspectj.weaver.ast.Literal.accept(Literal.java:29) at org.aspectj.weaver.bcel.BcelRenderer.recur(BcelRenderer.java:153) at org.aspectj.weaver.bcel.BcelRenderer.renderTest(BcelRenderer.java:119) at org.aspectj.weaver.bcel.BcelAdvice.getTestInstructions(BcelAdvice.java:587) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundClosure(BcelShadow.java:3050) at org.aspectj.weaver.bcel.BcelAdvice.implementOn(BcelAdvice.java:270) at org.aspectj.weaver.Shadow.implementMungers(Shadow.java:684) at org.aspectj.weaver.Shadow.implement(Shadow.java:471) at org.aspectj.weaver.bcel.BcelClassWeaver.implement(BcelClassWeaver.java:2825) at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:502) at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:115) at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1574) at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:1525) at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1305) at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1127) at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompilerAdapter.java:321) at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(AjCompilerAdapter.java:192) at org.aspectj.ajdt.internal.compiler.CompilerAdapter.ajc$afterReturning$org_aspectj_ajdt_internal_compiler_CompilerAdapter$2$f9cc9ca0(CompilerAdapter.aj:70) at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:367) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:887) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:244) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:199) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.incrementalBuild(AjBuildManager.java:170) at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:117) at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191) trouble in: public class com.foliofn.infra.logging.ExceptionThrowingClassForTest extends java.lang.Object: public org.apache.log4j.Logger log private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] public void <init>(): ALOAD_0 // Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest; this (line 5) INVOKESPECIAL java.lang.Object.<init> ()V constructor-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.<init>()) | ALOAD_0 // Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest; this (line 7) | ALOAD_0 // Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest; this | INVOKEVIRTUAL java.lang.Object.getClass ()Ljava/lang/Class; | INVOKESTATIC org.apache.log4j.Logger.getLogger (Ljava/lang/Class;)Lorg/apache/log4j/Logger; | PUTFIELD com.foliofn.infra.logging.ExceptionThrowingClassForTest.log Lorg/apache/log4j/Logger; | RETURN (line 5) constructor-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.<init>()) end public void <init>() public void throwRuntimeException(String) org.aspectj.weaver.MethodDeclarationLineNumber: 9:194 : method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwRuntimeException(java.lang.String)) | ALOAD_1 // Ljava/lang/String; message (line 10) | ASTORE_2 | GETSTATIC com.foliofn.infra.logging.ExceptionThrowingClassForTest.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; | ALOAD_0 | ACONST_NULL | ALOAD_2 | INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; | ASTORE_3 | ATHROW method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwRuntimeException(java.lang.String)) end public void throwRuntimeException(String) public void throwRuntimeException(String, Throwable) org.aspectj.weaver.MethodDeclarationLineNumber: 13:306 : method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwRuntimeException(java.lang.String, java.lang.Throwable)) | NEW java.lang.RuntimeException (line 14) | DUP | ALOAD_1 // Ljava/lang/String; message | ALOAD_2 // Ljava/lang/Throwable; nested | constructor-call(void java.lang.RuntimeException.<init>(java.lang.String, java.lang.Throwable)) | | INVOKESPECIAL java.lang.RuntimeException.<init> (Ljava/lang/String;Ljava/lang/Throwable;)V | constructor-call(void java.lang.RuntimeException.<init>(java.lang.String, java.lang.Throwable)) | ATHROW method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwRuntimeException(java.lang.String, java.lang.Throwable)) end public void throwRuntimeException(String, Throwable) public void throwException(String) throws java.lang.Exception org.aspectj.weaver.MethodDeclarationLineNumber: 17:444 : method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwException(java.lang.String)) | NEW java.lang.Exception (line 18) | DUP | ALOAD_1 // Ljava/lang/String; message | constructor-call(void java.lang.Exception.<init>(java.lang.String)) | | INVOKESPECIAL java.lang.Exception.<init> (Ljava/lang/String;)V | constructor-call(void java.lang.Exception.<init>(java.lang.String)) | ATHROW method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwException(java.lang.String)) end public void throwException(String) throws java.lang.Exception public void throwExceptionExtension(Object) throws java.lang.RuntimeException org.aspectj.weaver.MethodDeclarationLineNumber: 21:559 : method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwExceptionExtension(java.lang.Object)) | NEW com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension (line 22) | DUP | ALOAD_0 // Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest; this | ALOAD_1 // Ljava/lang/Object; someObject | constructor-call(void com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension.<init>(com.foliofn.infra.logging.ExceptionThrowingClassForTest, java.lang.Object)) | | INVOKESPECIAL com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension.<init> (Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest;Ljava/lang/Object;)V | constructor-call(void com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension.<init>(com.foliofn.infra.logging.ExceptionThrowingClassForTest, java.lang.Object)) | ATHROW method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwExceptionExtension(java.lang.Object)) end public void throwExceptionExtension(Object) throws java.lang.RuntimeException public void throwExceptionExtension(Object, Throwable) throws java.lang.RuntimeException org.aspectj.weaver.MethodDeclarationLineNumber: 25:705 : method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwExceptionExtension(java.lang.Object, java.lang.Throwable)) | NEW com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension (line 26) | DUP | ALOAD_0 // Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest; this | ALOAD_1 // Ljava/lang/Object; someObject | ALOAD_2 // Ljava/lang/Throwable; t | constructor-call(void com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension.<init>(com.foliofn.infra.logging.ExceptionThrowingClassForTest, java.lang.Object, java.lang.Throwable)) | | INVOKESPECIAL com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension.<init> (Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest;Ljava/lang/Object;Ljava/lang/Throwable;)V | constructor-call(void com.foliofn.infra.logging.ExceptionThrowingClassForTest$ExceptionExtension.<init>(com.foliofn.infra.logging.ExceptionThrowingClassForTest, java.lang.Object, java.lang.Throwable)) | ATHROW method-execution(void com.foliofn.infra.logging.ExceptionThrowingClassForTest.throwExceptionExtension(java.lang.Object, java.lang.Throwable)) end public void throwExceptionExtension(Object, Throwable) throws java.lang.RuntimeException static final RuntimeException init$_aroundBody0(com.foliofn.infra.logging.ExceptionThrowingClassForTest, String, org.aspectj.lang.JoinPoint): NEW java.lang.RuntimeException DUP ALOAD_1 INVOKESPECIAL java.lang.RuntimeException.<init> (Ljava/lang/String;)V (line 10) ARETURN end static final RuntimeException init$_aroundBody0(com.foliofn.infra.logging.ExceptionThrowingClassForTest, String, org.aspectj.lang.JoinPoint) end public class com.foliofn.infra.logging.ExceptionThrowingClassForTest public class com.foliofn.infra.logging.ExceptionThrowingClassForTest$AjcClosure1 extends org.aspectj.runtime.internal.AroundClosure: public void <init>(Object[]): ALOAD_0 ALOAD_1 INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V RETURN end public void <init>(Object[]) public Object run(Object[]): ALOAD_0 GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; ASTORE_2 ALOAD_2 BIPUSH 0 AALOAD CHECKCAST com.foliofn.infra.logging.ExceptionThrowingClassForTest ALOAD_2 BIPUSH 1 AALOAD CHECKCAST java.lang.String ALOAD_2 BIPUSH 2 AALOAD CHECKCAST org.aspectj.lang.JoinPoint INVOKESTATIC com.foliofn.infra.logging.ExceptionThrowingClassForTest.init$_aroundBody0 (Lcom/foliofn/infra/logging/ExceptionThrowingClassForTest;Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/RuntimeException; ARETURN end public Object run(Object[]) end public class com.foliofn.infra.logging.ExceptionThrowingClassForTest$AjcClosure1 when implementing on shadow constructor-call(void java.lang.RuntimeException.<init>(java.lang.String)) when weaving type com.foliofn.infra.logging.ExceptionThrowingClassForTest when weaving classes when weaving when batch building BuildConfig[Q:\eclipse.workspaces\folio2\.metadata\.plugins\org.eclipse.ajdt.core\fn_infra.aj.generated.lst] #Files=18
Actually, the error appears to be releated to the if() in the exceptionInitializer pointcut. If I remove the "&& if()" and change the signature the error is eliminated (with the full @Around adviced uncommented)
thanks for the small testcase - I have recreated this. I'd probably use code style aspects if I were you, the if() support in annotation style is a bit buggy.
Thanks for recreating! Too bad about @Aspect if()'s. We are using only @Aspect syntax. Is there a category/search criteria for @Aspect specific bugs so I can be on the lookout for gotchas?
tests for this have been committed (they are currently commented out in Ajc153tests)
ok, the problem here is the parameter binding is hopeless for annotation style. Here is the pointcut (highlights): @Pointcut("call(...) && this(caller) && args(exceptionMessage) && if()") public static boolean foo(Object caller, String exceptionMessage) { and here is the advice method (highlights): @Around("foo(caller, exceptionMessage)") public Object goo(ProceedingJoinPoint jp, Object caller, String exceptionMessage) { Code style does a lot of analysis to bind things correctly. Here the binding of caller and exceptionmessage for passing to them to foo() gets completely thrown by the addition of ProceedingJoinPoint in the advice method. In the end it kind of attempts to pass ProceedingJoinPoint and caller as the two parameters to foo. And blows up as shown. So I've made this situation work now. It is is still fragile but the rules are relatively straightforward - the parameter ordering for the if() must match the order in goo() but you are allowed special parameters ahead of the normal parameters (like ProceedingJoinPoint above). I've added 6 testcase variants for this and they are all OK. It will be easy to break it by violating this rule but at least a well written pointcut/advice pair will work as expected now.