Announcement Announcement Module
Collapse
No announcement yet.
NPE trying to autoproxy bean with factory method Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Which Spring version are you using ? Can you create a minimal test and upload it on forum ?

    Comment


    • #3
      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)

      Comment


      • #4
        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.

        Comment


        • #5
          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.

          Comment

          Working...
          X