Results 1 to 5 of 5

Thread: NPE trying to autoproxy bean with factory method

  1. #1
    Join Date
    Oct 2007
    Posts
    10

    Default NPE trying to autoproxy bean with factory method

    I have a Spring AOP autoproxying that works fine until the introduction of my new bean. The purpose of this new bean is for Properties handling. Its bean definition is:

    Code:
    <!-- Wrap policy parameters used in analysis from .properties file. 
    This is initialised using static constructor 'initialise'. 
    Not referenced elsewhere as a bean, but accessed directly as static methods. -->
    <bean id="analysisParameters"
    	class="pkg.AnalysisParameters" 
            factory-method="initialise">
    	<constructor-arg>
    		<!-- Load in the policy parameters used in analysis from .properties file -->
     	 	<bean id="analysisParametersLoader"
                   class="org.springframework.beans.factory.config.PropertiesFactoryBean" >
    		<property name="location"
    				value="classpath:parameters.properties" />
    		</bean>
    	</constructor-arg>
    </bean>

    Code:
    public class AnalysisParameters {
    ...
    	public static void initialise(Properties propertiesFromFile) {
    		if (properties == null) {
    			properties = propertiesFromFile;
    			populateParameters();
    		}
    	}
    ...
    }
    As you can see it has a factory method. It works completely as intended when autoproxying is off.

    When I run my unit tests with autoproxying on
    Code:
    <aop:aspectj-autoproxy>
    	<aop:include name="calculationsAdvisor" />
    	<aop:include name="loggingAdvisor" /> 
    </aop:aspectj-autoproxy>
    and the above bean definition included, then I get the error:

    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'analysisParameters' defined in file [../project/bin/applicationContext/service/AnalysisService.xml]: Initialization of bean failed; nested exception is java.lang.NullPointerException
    Caused by: java.lang.NullPointerException
    	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:286)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:312)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1180)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
    	at org.springframework.test.AbstractSingleSpringContextTests.createApplicationContext(AbstractSingleSpringContextTests.java:199)
    	at org.springframework.test.AbstractSingleSpringContextTests.loadContextLocations(AbstractSingleSpringContextTests.java:179)
    	at org.springframework.test.AbstractSingleSpringContextTests.loadContext(AbstractSingleSpringContextTests.java:158)
    	at org.springframework.test.AbstractSpringContextTests.getContext(AbstractSpringContextTests.java:105)
    	at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:87)
    	at junit.framework.TestCase.runBare(TestCase.java:128)
    	at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
    	at junit.framework.TestResult$1.protect(TestResult.java:110)
    	at junit.framework.TestResult.runProtected(TestResult.java:128)
    	at junit.framework.TestResult.run(TestResult.java:113)
    	at junit.framework.TestCase.run(TestCase.java:120)
    	at junit.framework.TestSuite.runTest(TestSuite.java:228)
    	at junit.framework.TestSuite.run(TestSuite.java:223)
    	at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:35)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    This is regardless of pointcut definitions and advice, so seems to me to be a proxying problem, as suggested by the stack trace as well.

    Any ideas?

    Thanks
    Brad

  2. #2
    Join Date
    Mar 2007
    Posts
    515

    Default

    Which Spring version are you using ? Can you create a minimal test and upload it on forum ?

  3. #3
    Join Date
    Oct 2007
    Posts
    10

    Default

    Thanks Andrei

    Basic test class:
    Code:
    import static org.junit.Assert.assertTrue;
    import org.junit.Test;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class BasicAOPTest {
    
    	@Test
    	public void testIt() {
    		AbstractApplicationContext context = new ClassPathXmlApplicationContext(
    				new String[] { "classpath:**/AOPConfig.xml",
    						"classpath:**/BasicAOPTestConfig.xml" });
    		context.refresh();
    
    		assertTrue(true);
    	}
    }
    AOPConfig.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: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/aop
    							http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    
    	<!-- Configuration for the aspects that apply to the application -->
    
    	<!-- Analysis calculations AOP -->
     	<bean id="calculationsAdvisor"
    		class="pkg.CalculationsAdvisor">
    	</bean>
    
    	<aop:aspectj-autoproxy>
    		<aop:include name="calculationsAdvisor" />
    	</aop:aspectj-autoproxy>
    
    </beans>
    BasicAOPTestConfig.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"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    							http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    	<bean id="analysisParameters"
    		class="pkg.AnalysisParameters"
    		factory-method="initialise">
    		<constructor-arg>
    			<!-- Load in the policy parameters used in analysis from .properties file -->
    			<bean id="analysisParametersLoader"
    				class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    				<property name="location"
    					value="classpath:parameters.properties" />
    			</bean>
    		</constructor-arg>
    	</bean>
    </beans>
    Gives:
    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'analysisParameters' defined in file [/home/brad/_projects/workspaceTransit/OPermit/bin/nz/govt/transit/utils/aop/BasicAOPTestConfig.xml]: Initialization of bean failed; nested exception is java.lang.NullPointerException
    Caused by: java.lang.NullPointerException
    	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:286)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:312)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1180)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:91)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:75)
    	at nz.govt.transit.utils.aop.BasicAOPTest.testIt(BasicAOPTest.java:12)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:585)
    	at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
    	at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
    	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
    	at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
    	at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
    	at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
    	at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
    	at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
    	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
    	at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

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

    Default

    The problem seems to be that you are not returning an object from your factory method:

    Code:
    public static void initialise(Properties propertiesFromFile) {
    ...
    When a factory-method is specified, Spring will call it to create an instance of your bean, so the method should return an object.
    Mike Bingham

  5. #5
    Join Date
    Oct 2007
    Posts
    10

    Default

    That's it! Exactly right, thanks a lot.



    The reason this wasn't obvious to me is that I'm utilising the class statically and just using Spring to initialise the class, then ignoring Spring's bean of it. I've resolved it now by just returning a Boolean and now it's happy.

Posting Permissions

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