Results 1 to 4 of 4

Thread: Advisor Not Being Called

Hybrid View

  1. #1

    Unhappy 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. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    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.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    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?

  4. #4

    Talking 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...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •