Results 1 to 8 of 8

Thread: Autowired objects in aspect are null once code is run

Hybrid View

  1. #1
    Join Date
    Oct 2010
    Posts
    10

    Default Autowired objects in aspect are null once code is run

    Hi, I am having problems autowiring the entity manager into my Aspect.

    When I add a constructor to my Aspect and put a break point on it I can see it hits twice, therefore two objects created. The first time the aspect has an object id of 52. I continue and the breakpoint hits again, this time the Aspect object has an id of 76. My third breakpoint is on a setter for a bean property configured in the application context xml. This refers to the second instance of the object 76 which I can see does have the @PersistenceContext em set correctly. As my test executes and my aspect is launched but the instance used is object 52, this one has null values for the entity manager.

    I have copied the stack for each instance.
    Aspect object id 52

    Code:
    Thread [main] (Suspended (breakpoint at line 20 in EntityManagerAspectImpl))	
    	EntityManagerAspectImpl.<init>() line: 20	
    	EntityManagerAspectImpl.ajc$postClinit() line: 1	
    	EntityManagerAspectImpl.<clinit>() line: 1	
    	J9VMInternals.initializeImpl(Class) line: not available [native method]	
    	J9VMInternals.initialize(Class) line: 196	
    	NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]	
    	NativeConstructorAccessorImpl.newInstance(Object[]) line: 67	
    	DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45	
    	Constructor<T>.newInstance(Object...) line: 522	
    	BeanUtils.instantiateClass(Constructor, Object[]) line: 100	
    	CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory) line: 61	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateBean(String, RootBeanDefinition) line: 877	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object[]) line: 839	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 440	
    	AbstractAutowireCapableBeanFactory$1.run() line: 409	
    	AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 219	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380	
    	AbstractBeanFactory$1.getObject() line: 264	
    	DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 222	
    	DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261	
    	DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class, Object[]) line: 185	
    	DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 164	
    	DefaultListableBeanFactory.preInstantiateSingletons() line: 429	
    	GenericApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 728	
    	GenericApplicationContext(AbstractApplicationContext).refresh() line: 380	
    	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 79	
    	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    	Method.invoke(Object, Object...) line: 618	
    	GLExtractControlTest(AbstractJpaTests).runBare() line: 230	
    	TestResult$1.protect() line: 106	
    	TestResult.runProtected(Test, Protectable) line: 124	
    	TestResult.run(TestCase) line: 109	
    	GLExtractControlTest(TestCase).run(TestResult) line: 120	
    	TestSuite.runTest(Test, TestResult) line: 230	
    	TestSuite.run(TestResult) line: 225	
    	JUnit38ClassRunner.run(RunNotifier) line: 81	
    	JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 45	
    	TestExecution.run(ITestReference[]) line: 38	
    	RemoteTestRunner.runTests(String[], String, TestExecution) line: 460	
    	RemoteTestRunner.runTests(TestExecution) line: 673	
    	RemoteTestRunner.run() line: 386	
    	RemoteTestRunner.main(String[]) line: 196
    Aspect object id 76

    Code:
    Thread [main] (Suspended (breakpoint at line 20 in EntityManagerAspectImpl))	
    	EntityManagerAspectImpl.<init>() line: 20	
    	NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]	
    	NativeConstructorAccessorImpl.newInstance(Object[]) line: 67	
    	DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45	
    	Constructor<T>.newInstance(Object...) line: 522	
    	BeanUtils.instantiateClass(Constructor, Object[]) line: 100	
    	CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory) line: 61	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateBean(String, RootBeanDefinition) line: 877	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object[]) line: 839	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 440	
    	AbstractAutowireCapableBeanFactory$1.run() line: 409	
    	AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 219	
    	DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380	
    	AbstractBeanFactory$1.getObject() line: 264	
    	DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 222	
    	DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261	
    	DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class, Object[]) line: 185	
    	DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 164	
    	DefaultListableBeanFactory.preInstantiateSingletons() line: 429	
    	GenericApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 728	
    	GenericApplicationContext(AbstractApplicationContext).refresh() line: 380	
    	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 79	
    	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    	Method.invoke(Object, Object...) line: 618	
    	GLExtractControlTest(AbstractJpaTests).runBare() line: 230	
    	TestResult$1.protect() line: 106	
    	TestResult.runProtected(Test, Protectable) line: 124	
    	TestResult.run(TestCase) line: 109	
    	GLExtractControlTest(TestCase).run(TestResult) line: 120	
    	TestSuite.runTest(Test, TestResult) line: 230	
    	TestSuite.run(TestResult) line: 225	
    	JUnit38ClassRunner.run(RunNotifier) line: 81	
    	JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 45	
    	TestExecution.run(ITestReference[]) line: 38	
    	RemoteTestRunner.runTests(String[], String, TestExecution) line: 460	
    	RemoteTestRunner.runTests(TestExecution) line: 673	
    	RemoteTestRunner.run() line: 386	
    	RemoteTestRunner.main(String[]) line: 196
    I am so close to it all working I'm sure, any help would be fantastic.
    Thanks.

  2. #2
    Join Date
    Jul 2010
    Location
    Venice, Italy
    Posts
    709

    Default

    I believe you have some misconfiguration...you probably instantiate two different Spring Application Contexts, or have misconfigured AOP and get proxies of proxies, or something like that. You should post your full configuration.

    BTW you shouldn't use entity managers directly into an aspect. You should follow the dao pattern and create daos for your database operations, then wire your daos to your services and aspects, but this is just a design suggestion, it has nothing to do with the error.

  3. #3
    Join Date
    Oct 2010
    Posts
    10

    Default

    Ok thanks, I've had another look and cannot for the life of me work out what configuration I have screwed up. I appreciate the help! Let me know if there's anything else I have missed. I am injecting the entity manager so I can call flush and generate an id which is used elsewhere.

    Thanks again!

    Aspect

    Code:
    @Aspect
    @Configurable
    public class EntityManagerAspectImpl {
    
    	public EntityManagerAspectImpl() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    
    	private Logger LOG = Logger.getLogger(this.getClass());
    
    	@PersistenceContext
    	private EntityManager em;
    	
    	protected EntityManagerFactory emf;
    	
    	@Pointcut("execution(* net.targetgroup.accounts.base.model.GLExtractControl.*(..))")
    	public void expireGlExtractKeyAspect() {}
    
    	@After("expireGlExtractKeyAspect()")
    	public void flush() {
    		LOG.debug("Aspect entity manger flush called");
    
    		em.flush();
    		
    		LOG.debug("Aspect entity manger flush finished");
    	}
    
    	public EntityManagerFactory getEmf() {
    		return emf;
    	}
    
    	public void setEmf(EntityManagerFactory emf) {
    		this.emf = emf;
    	}
    
    }
    Aspect Spring configuration

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:util="http://www.springframework.org/schema/util"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
    	
    	<context:load-time-weaver aspectj-weaving="on"/>
    	
    
    	<aop:aspectj-autoproxy/>
    
    	<bean id="myAspect" class="net.targetgroup.accounts.base.aspect.EntityManagerAspectImpl">
    	   <property name="emf" ref="entityManagerFactory" />
    	</bean>
    
    </beans>
    aop.xml

    Code:
    <aspectj>
    
        <weaver>
            <!-- only weave classes in our application-specific packages -->
            <include within="net.targetgroup.accounts.base.model.*"/>
        </weaver>
    
        <aspects>
            <!-- weave in just this aspect -->        
            <aspect name="net.targetgroup.accounts.base.aspect.EntityManagerAspectImpl"/>
        </aspects>
    
     </aspectj>
    Base Spring context

    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:aop="http://www.springframework.org/schema/aop"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    	<context:component-scan
    		base-package="net.targetgroup.accounts.base.persistence" />
    	<context:component-scan
    		base-package="net.targetgroup.product.service,net.targetgroup.product.persistence" />
    	
    	<context:property-placeholder
    		location="classpath:application.properties, classpath:guts.properties" />
    
    </beans>

  4. #4
    Join Date
    Jul 2010
    Location
    Venice, Italy
    Posts
    709

    Default

    <context:load-time-weaver aspectj-weaving="on"/>


    <aop:aspectj-autoproxy/>
    Your problem lies in these two lines. The first line activates AspectJ weaving, the second one activates annotated Spring AOP. Thus, your annotated Aspect class gets read two times, and advised classes get both weaved by aspectJ AND proxied by Spring AOP.
    You will have to choose only one AOP strategy, either disable Spring AOP by deleting the aop:aspectj-autoproxy line OR disable AspectJ by removing the context:load time weaver element and deleting the aop.xml file (I assume, since you took the pain of configuring full-blown AspectJ, that you'll want to remove Spring AOP).

    After that, everything should work as expected.

  5. #5

    Default

    Also @Configurable is unnecessary in this case

  6. #6

    Question

    Is this topic resolved? I met the same problem and I checked my configurations according to the previous reply, but only <aop:aspectj-autoproxy/> is used

    Config files:
    spring-test.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:context="http://www.springframework.org/schema/context"
      xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
      <import resource="classpath:spring-common.xml" />
      <import resource="classpath:spring-ldap.xml" />
    
      <context:annotation-config />
      <context:component-scan base-package="cn.youcredit.thread.auth.service" />
      <context:component-scan base-package="cn.youcredit.thread.auth.dao" />
      <context:component-scan base-package="cn.youcredit.thread.auth.web" />
      <aop:aspectj-autoproxy />
      <mvc:annotation-driven />
    
      <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
        <property name="url" value="jdbc:derby:thread_auth;create=true" />
      </bean>
      
      <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <!-- Inject from dependent projects -->
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses" ref="models" />
        <property name="hibernateProperties">
          <value>
            hibernate.dialect=org.hibernate.dialect.DerbyTenSevenDialect
            hibernate.cache.use_second_level_cache=true
            <!-- hibernate.cache.use_query_cache=true -->
            hibernate.show_sql=true
            hibernate.cache.region.factory_class=org.hibernate.cache.infinispan.InfinispanRegionFactory
            hibernate.hbm2ddl.auto=create
          </value>
        </property>
      </bean>
    </beans>
    Code:
    package cn.youcredit.thread.auth.aop;
    
    @Aspect
    public class UserAspect {
        @Autowired
        private UserGroupDAO groupDAO;
        @Autowired
        private UserPrivilegeMappingDAO userPrivilegeMappingDAO;
        @Autowired
        private UserPrivilegeGroupMappingDAO userPrivilegeGroupMappingDAO;
    }
    And I assured that no component scan for cn.youcredit.thread.auth.aop is defined in spring-common.xml nor spring-ldap.xml. In JUnit runtime, all the DAOs are null.

Posting Permissions

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