Announcement Announcement Module
Collapse
No announcement yet.
Advisor Not Being Called Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Advisor Not Being Called

    For someone reason my ThrowsAdvice is not being invoked, even when I deliberately throw an exception to test it. I'm not getting any errors (other than the expected stack trace from the deliberately thrown exception), but the advice isn't executed. Configuration file:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans 
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
          http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       "
       default-autowire="byName"
    >
       <bean id="maintenanceTransactionTypeDao" class="com.uprr.db.dao.spring.stats.MaintenanceTransactionTypeDAO" />
       <bean id="maintenanceItemTypeDao"        class="com.uprr.db.dao.spring.stats.MaintenanceItemTypeDAO"        />
       <bean id="maintenanceTransactionDao"     class="com.uprr.db.dao.spring.stats.MaintenanceTransactionDAO"     />
       <bean id="errorAdvisor"                  class="com.uprr.aop.ThrowAdvice"                                   />
    
       <aop:config>
         <aop:pointcut id="allMethods" expression="execution(* *(..))" />
         <aop:advisor pointcut-ref="allMethods" advice-ref="errorAdvisor" />
       </aop:config>
    
    </beans>
    Advice:
    Code:
    package com.uprr.aop;
    
    import java.lang.reflect.Method;
    
    import org.apache.log4j.Logger;
    import org.springframework.aop.ThrowsAdvice;
    
    import com.uprr.util.ApiLogger;
    
    //----------------------------------------------------------------------------------------------
    /**
     * Invoked when an advised class throws a {@link Throwable}. The main purpose of this advice is
     * to ensure that all errors are recorded in the log.
     */
    public class ThrowAdvice implements ThrowsAdvice {
    
    //-----------------------------------------------------------------------
    /**
     * Reacts to an exception being thrown. Currently, this method just logs the exception.
     * @param method The throwing method.
     * @param args Arguments to the throwing method.
     * @param thrower The throwing object.
     * @param error The item thrown.
     * @throws RuntimeException if the API logger has not been configured.
     */
    public void afterThrowing(final Method method, final Object[] args, final Object thrower, 
    	final Throwable error) {
    System.out.println("Entered afterThrowing()");	
    	final Logger logger = Logger.getLogger(ApiLogger.NAME);
    	if (logger == null) {
    		String message = ApiLogger.NOT_FOUND;
    		message += " Error that could not be recorded: " + error;
    		throw new RuntimeException(message);
    	}
    	logger.error("An exception was thrown by " + thrower + '.' + method + '(' + args + ')');
    	logger.error("Details: " + error);
    }
    //-----------------------------------------------------------------------
    }
    Code that should cause the advice to execute:
    Code:
    import java.util.Iterator;
    
    import org.apache.log4j.Logger;
    import org.apache.log4j.xml.DOMConfigurator;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.uprr.db.dao.spring.stats.MaintenanceTransactionTypeDAO;
    
    //-----------------------------------------------------------------------
    public class Test
    {
    public static final Logger logger = Logger.getLogger("com.uprr.tns.test");
    
    //-----------------------------------------------------------------------
    public static void main(final String[] args) throws Exception
    {
    	DOMConfigurator.configure("log4j-test.xml");
    	/**
    	 * In production:
    	 * getRootLogger().setLevel(Level.ERROR);
    	 */
    	final String configFiles[] = {"spring-test.xml", "spring-tns-api.xml"};
    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(configFiles);
    
    	testTransactionTypes(context);
    	testItemTypes(context);
    }
    //-----------------------------------------------------------------------
    public static void testItemTypes(ClassPathXmlApplicationContext context) throws Exception
    {
    // Deliberately throw an exception to see if AOP catches it
    throw new Exception("Dummy exception to test AOP");
    /*
    	MaintenanceItemTypeDAO dao = MaintenanceItemTypeDAO.getBean(context);
    	Iterator iterator = dao.getAllTypes().iterator();
    	while (iterator.hasNext()) {
    		logger.info(iterator.next());
    	}
    	final Integer systemNumber = new Integer(3);
    	logger.info("Item type # " + systemNumber + " = " + dao.getDescription(systemNumber));
    */	
    }
    //-----------------------------------------------------------------------
    public static void testTransactionTypes(ClassPathXmlApplicationContext context) throws Exception
    {
    	MaintenanceTransactionTypeDAO dao = MaintenanceTransactionTypeDAO.getBean(context);
    	Iterator iterator = dao.getAllTypes().iterator();
    	while (iterator.hasNext()) {
    		logger.info(iterator.next());
    	}
    	final Integer systemNumber = new Integer(3);
    	logger.info("Transaction type # " + systemNumber + " = " + dao.getDescription(systemNumber));
    }
    //-----------------------------------------------------------------------
    }

  • #2
    Well your test is pretty useless for testing your advice... Remember that your DAO is adviced NOT your test class, currently you are testing the advice on your testclass.. So if you want to test anything throw the exception INSIDE your DAO.

    Comment


    • #3
      Why do you say that only the DAO is advised? The pointcut expression "execution(* *(..))" would cause ALL classes in the app to be advised, wouldn't it? At least, that was our intent? If it doesn't do that, how would write it so it does?

      Comment


      • #4
        Got It!

        Doh! I finally got it. The exception is thrown by a class that's not a managed bean, so Spring is ignorant of it and can't advise it.

        Thanks for the patience...

        Comment

        Working...
        X