Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: AspectJ @Before problem

  1. #1

    Default AspectJ @Before problem

    Having a problem getting my @Before Aspect to not cause havock upon Spring startup. Removing the @Before but leaving the @Aspect allows Spring to start.

    applicationContext.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           	xmlns:tx="http://www.springframework.org/schema/tx"
           	xmlns:context="http://www.springframework.org/schema/context"
           	xmlns:aop="http://www.springframework.org/schema/aop"
    	    xsi:schemaLocation="
    	    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    	    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    	    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.1.xsd
    	    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
        	default-autowire="byName">
        	
        <!-- Enable annotation config -->
    	<context:annotation-config/>
    	
    	<!-- Enable AOP annotations -->
    	<aop:aspectj-autoproxy/>
    
    	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        	<property name="locations">
            	<value>classpath:jdbc.properties</value>
        	</property>
        	<property name="ignoreResourceNotFound" value="true"/>
    	</bean>
    
    	<!-- Transaction behavior based on annotations -->
      	<tx:annotation-driven order="200"/>
    
    	<!-- Data source -->
    	<bean id="targetDataSource" 
    			class="org.apache.commons.dbcp.BasicDataSource" 
    			destroy-method="close" depends-on=" ">
    		<property name="driverClassName" value="${jdbc.driverClassName}"/>
    		<property name="url" value="${jdbc.url}"/>
    		<property name="username" value="${jdbc.username}"/>
    		<property name="password" value="${jdbc.password}"/>
    		<property name="maxActive" value="100"/>
    		<property name="maxWait" value="500"/>
    		<property name="validationQuery" value="SELECT SYSDATE FROM DUAL"/>
    	</bean>
    	
    	<bean id="dataSource"
    			class="com.mycompany.commons.data.datasource.CurrentStudyIdAwareDataSourceProxy">
    	</bean>
    
    	<!-- Hibernate -->
    	<bean id="sessionFactory"
    			class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    		<property name="annotatedClasses">
    			<list>
    				<value>com.mycompany.domain.Study</value>
    				<value>com.mycompany.domain.User</value>
    				<value>com.mycompany.domain.WebServiceSession</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
    				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
    				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
    				<prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
    				<prop key="hibernate.max_fetch_depth">3</prop>
    			</props>
    		</property>
    	</bean>
    	
    	<!-- Transaction -->
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"/>
    	
    	<!-- DAOs -->
    	<bean id="siteDAO" class="com.mycompany.commons.data.dao.impl.SiteDAOGenericHibernateImpl"/>
    	<bean id="userDAO" class="com.mycompany.commons.data.dao.impl.UserDAOGenericHibernateImpl"/>
    	<bean id="webServiceSessionDAO" class="com.mycompany.commons.data.dao.impl.WebServiceSessionDAOGenericHibernateImpl"/>
    	<bean id="studyDAO" class="com.mycompany.commons.data.dao.impl.StudyDAOGenericHibernateImpl"/>
    	
    	<!-- NativeJdbcExtractor for the Commons DBCP connection pool above -->
    	<bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" lazy-init="true"/>
    
    	<!-- LobHandler for Oracle JDBC drivers -->
    	<bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true"/>
    
    	<!-- Aspects -->
    	<bean class="com.mycompany.commons.data.support.CurrentStudyIdAspect"/>
    </beans>
    CurrentStudyIdAspect
    Code:
    package com.mycompany.commons.data.support;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.annotation.Order;
    
    import com.mycompany.commons.data.dao.WebServiceSessionDAO;
    import com.mycompany.domain.WebServiceSession;
    
    @Aspect
    @Order(100)
    public class CurrentStudyIdAspect {
    
    	private static Log logger = LogFactory.getLog(CurrentStudyIdAspect.class);
    	
    	@Autowired
    	private WebServiceSessionDAO webServiceSessionDAO;
    	
    	@Before("@annotation(com.mycompany.commons.data.annotation.CurrentStudyIdFromToken) && args(token, ..)")
    	public void setCurrentStudyIdFromToken(byte[] token) {
    		WebServiceSession session = webServiceSessionDAO.findByToken(token);
    		if (token != null) {
    			if (session != null) {
    				if (session.getStudy() != null) {
    					CurrentStudyIdHolder.setStudyId(session.getStudy().getId());
    				}
    				else {
    					logger.debug("session.study null");
    				}
    			}
    			else {
    				logger.debug("session null");
    			}
    		}
    		else {
    			logger.debug("token null or not size 16");
    		}
    	}
    	
    }
    CurrentStudyId
    Code:
    package com.mycompany.commons.data.annotation;
    
    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)
    @Target(value = { ElementType.METHOD })
    @Documented
    public @interface CurrentStudyIdFromToken {
    }

  2. #2

    Default

    Stack trace from JUnit 4.4 test
    Code:
    [junit] Running com.mycompany.commons.testsuites.TestCurrentStudyId
        [junit] Testsuite: com.mycompany.commons.testsuites.TestCurrentStudyId
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0.886 sec
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0.886 sec
        [junit] ------------- Standard Output ---------------
        [junit] [WARN,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer] Could not load properties from class path resource [jdbc.properties]: class path resource [jdbc.properties] cannot be opened because it does not exist
        [junit] ------------- ---------------- ---------------
        [junit] 
        [junit] Testcase: verifyFindStudy took 0.011 sec
        [junit]     Caused an ERROR
        [junit] Error creating bean with name 'org.springframework.context.annotation.internalRequiredAnnotationProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot create inner bean '(inner bean)' of type [org.springframework.transaction.interceptor.TransactionInterceptor] while setting bean property 'transactionInterceptor'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'targetDataSource' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Failed to bind all argument names: 1 argument(s) could not be bound
        [junit] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.annotation.internalRequiredAnnotationProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot create inner bean '(inner bean)' of type [org.springframework.transaction.interceptor.TransactionInterceptor] while setting bean property 'transactionInterceptor'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'targetDataSource' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Failed to bind all argument names: 1 argument(s) could not be bound
        [junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:557)
        [junit]     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:238)
        [junit]     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:167)
        [junit]     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:235)
        [junit]     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:167)
        [junit]     at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:867)
        [junit]     at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:588)
        [junit]     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:351)
        [junit]     at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:93)
        [junit]     at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:44)
        [junit]     at org.springframework.test.context.TestContext.buildApplicationContext(TestContext.java:127)
        [junit]     at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:167)
        [junit]     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:58)
        [junit]     at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:184)
        [junit]     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:95)
        [junit]     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:144)
        [junit] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot create inner bean '(inner bean)' of type [org.springframework.transaction.interceptor.TransactionInterceptor] while setting bean property 'transactionInterceptor'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'targetDataSource' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Failed to bind all argument names: 1 argument(s) could not be bound
        [junit]     at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:219)
        [junit]     at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121)
        [junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1218)
        [junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:986)
        [junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
        [junit]     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:238)
        [junit]     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:167)
        [junit]     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:235)
        [junit]     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:167)
        [junit]     at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:87)
        [junit]     at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:98)
        [junit]     at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:83)
        [junit]     at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:84)
        [junit]     at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:66)
        [junit]     at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:296)
        [junit]     at
    ......

  3. #3

    Default

    TestCurrentStudyIdAspect
    Code:
    package com.mycompany.commons.support;
    
    import static org.junit.Assert.assertNotNull;
    import static org.junit.Assert.assertTrue;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.annotation.Rollback;
    
    import com.mycompany.commons.data.annotation.CurrentStudyIdFromToken;
    import com.mycompany.commons.data.dao.StudyDAO;
    import com.mycompany.commons.data.dao.UserDAO;
    import com.mycompany.commons.data.dao.WebServiceSessionDAO;
    import com.mycompany.commons.data.support.CurrentStudyIdHolder;
    import com.mycompany.domain.Study;
    import com.mycompany.domain.User;
    import com.mycompany.domain.WebServiceSession;
    
    public class TestCurrentStudyIdAspect extends CommonTestCase {
    
    	@Autowired
    	private WebServiceSessionDAO webServiceSessionDAO;
    	@Autowired
    	private UserDAO userDAO;
    	@Autowired
    	private StudyDAO studyDAO;
    	
    	@Before
    	@Rollback(false)
    	public void createSession() {
    		WebServiceSession session = new WebServiceSession();
    		User user = userDAO.findById(DEFAULT_USER_ID);
    		session.setUser(user);
    		Study study = studyDAO.findById(DEFAULT_STUDY_ID);
    		session.setStudy(study);
    		webServiceSessionDAO.saveOrUpdate(session);
    	}
    	
    	@After
    	@Rollback(false)
    	public void destroySession() {
    		deleteFromTables("HD.WEBSERVICE_SESSION");
    	}
    	
    	@Test
    	public void verifyFindStudy() throws Exception {
    		CurrentStudyIdHolder.setStudyId(999L);
    		User user = userDAO.findById(DEFAULT_USER_ID);
    		WebServiceSession session = webServiceSessionDAO.findByUser(user);
    		assertNotNull("WebServiceSession Study null", session.getStudy());
    		verifyAspectFired(session.getToken());
    	}
    	
    	@CurrentStudyIdFromToken
    	public void verifyAspectFired(byte[] token) {
    		assertTrue("StudyId still 999", CurrentStudyIdHolder.getStudyId() != 999);
    	}
    	
    	
    	
    }
    I've left out other irrelevant classes.

  4. #4

    Default

    So I managed to get it to startup without errors by replacing the asm*.jar and cglib*.jar from Hibernate with Spring's. But I cannot get the Aspect to fire.

  5. #5

    Default

    Anybody? I just need to fire my aspect before the @Transactional by specifying my own annotation. I can't seem to make it fire.

  6. #6

    Default

    Not to sound unhelpful, but could you try to make the example as minimal as possible?
    If you think it's a Spring AOP problem, removing annotation-driven IoC etc might be a good idea. What version of spring are you using? Did you try the latest stable release (2.0.7)?

  7. #7

    Default

    I'm using 2.1-m4, but I tried 2.0.6 and 2.0.7. I even tried not using the annotations. Oh well. I'll find another way.

  8. #8

    Default

    Can you provide a minimal example (just using a static main() to load a context and call a bean) that demonstrates the problem?

  9. #9
    Join Date
    Sep 2007
    Location
    Oceanside, CA
    Posts
    187

    Default

    Based on the code samples you provided, it looks like the aspect might not be firing because you've added the @CurrentStudyIdFromToken annotation to a method on an object which is not managed by Spring (in this case, TestCurrentStudyIdAspect.verifyAspectFired()) . Spring AOP will only proxy objects created by the Spring container.
    Mike Bingham

  10. #10

    Default

    Interesting. I'll try adjusting my applicationContext.xml file. Thanks. I'll post back.

Posting Permissions

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