Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] After Advice not called if using Reflection API

Hello,

First of all, I'm a newbie with AOP. I'm learning aspectJ framework

I'm testing the "exception introduction pattern" example ( ch11.4.2) from the "AspectJ in action" book.

The sample works great until you invoke the caller object using reflection API. The PreserveCheckedException advice code (described below ) is NOT invoked anymore.

Once the the ConcernAspect around advice throws the ConcernRuntimeException, this exception is directly wrapped within an java.lang.reflect.InvocationTargetException .

The issue is not related to the sample but to some side effect between reflection framework exception handling and AspectJ weaving.

How can we make the PreserveBusinessException advice code invoked in this special case ?


Thanks for your advice! ;)

-herve




///////////////////  test program //////////////////////////////
//

import java.lang.reflect.Method;


public class TestException {
    public static void main(String[] args) {
    BusinessClass bc = new BusinessClass();
   
/*   
     //works fine!. PreserveBusinessException Advice code is invoked
     bc.businessMethod1();
    try {
        bc.businessMethod2();
    } catch (Exception ex) {
        // Do something...
        // Log it, execute recovery mechanism, etc.
        System.out.println ("Caught:" + ex);
    }
*/   

    try {

        //PreserveBusinessException Advice code is not invoked
       
        Class cl=Class.forName ("BusinessClass");
        Method method = cl.getMethod("businessMethod2", null);
        method.invoke(bc, null);

       
       
    } catch (Exception ex) {
        // Do something...
        // Log it, execute recovery mechanism, etc.
        System.out.println("Caught:" + ex);
    }
  }
}

////////////////////////  abstract aspect class ///////////////////////

public abstract aspect ConcernAspect {
    abstract pointcut operations();

    Object around() : operations() {
    try {
        return proceed();
    }
     catch (Throwable ex) {
        // do something
        throw new ConcernRuntimeException(ex);
    }
 }
}


////////////////////////  PreserveBusinessException : aspect which captures all the methods throwing a ConcernRuntimeException and throws the cause instead ///////////////////////

public aspect PreserveBusinessException {
    declare precedence: PreserveBusinessException, ConcernAspect+;

    after() throwing(ConcernRuntimeException ex) throws BusinessException: call(* *.*(..) throws BusinessException) {
    Throwable cause = ex.getCause();
    System.out.println("PreserveBusinessException advice called:" + ex);

    if (cause instanceof BusinessException) {
        throw (BusinessException)cause;
    }
    throw ex;
    }
}


////////////////////////  business concrete aspect implementation class ///////////////////////

public aspect BusinessConcernAspect extends ConcernAspect {
    pointcut operations() : execution(* BusinessClass.business*());
}


////////////////////////  businessClass ///////////////////////

public class BusinessClass {
    public void businessMethod2() throws BusinessException, IllegalStateException{
    // business logic...
    throw new BusinessException();
    }
}


////////////////////////  BusinessException class ///////////////////////

public class BusinessException extends Exception {
}

////////////////////////  ConcernRuntimeException class ///////////////////////

public class ConcernRuntimeException extends RuntimeException {
    public ConcernRuntimeException(Throwable cause) {
    super(cause);
    }
}

  

Back to the top