Announcement Announcement Module
Collapse
No announcement yet.
Problem with application context and injecting beans. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with application context and injecting beans.

    Hi folks.
    Bit of a newbie question here... but I've been banging my head about this all weekend so I decided to come to the experts!

    Ok... I have an application context that pretty much looks like this:

    Code:
        <!--Script results data access object&#58; JDBC implementation -->
        <bean id="scriptResultsDAO" class="com.banana.upload.dao.impl.ScriptResultsDAOImpl" lazy-init="false">
            <property name="dataSource"><ref local="dataSource"/></property>
        </bean>
       
        <!--
            - A parent bean definition which is a base definition for transaction proxies.
            - It's marked as abstract, since it's not supposed to be instantiated itself.
            - We set shared transaction attributes here, following our naming patterns.
            - The attributes can still be overridden in child bean definitions.
        -->
        <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
              abstract="true">
            <property name="transactionManager"><ref bean="transactionManager"/></property>
            <property name="transactionAttributes">
                <props>
                    <prop key="insert*">PROPAGATION_REQUIRED</prop>
                    <prop key="update*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean>     
       
        <!--
          - Batch Upload primary business object &#40;default implementation&#41;, as an inner bean wrapped
            - by an outer transactional proxy.
            -->
        <bean id="uploader" parent="baseTransactionProxy">
            <property name="target">
                <bean class="com.banana.upload.domain.impl.UploaderImpl">           
                  <property name="scriptResultsDAO"><ref bean="scriptResultsDAO"/></property>
                </bean>
            </property>
        </bean>
    And on using a class path application context to initialise this I'm running into problems:
    Code:
        &#91;junit&#93; Caused by&#58; org.springframework.beans.factory.BeanCreationException&#58;
    Error creating bean with name 'com.banana.upload.domain.impl.UploaderImpl' def
    ined in class path resource &#91;applicationContext.xml&#93;&#58; Error setting property values; nested exception is org.springframework.beans.PropertyAccessExceptionsException&#58; PropertyAccessExceptionsException &#40;1 errors&#41;; nested propertyAccessExceptions are&#58; &#91;org.springframework.beans.MethodInvocationException&#58; Property 'scriptR
    esultsDAO' threw exception; nested exception is java.lang.NullPointerException&#58;
    null&#93;
    I'm initialising like this:
    Code:
       /**
        * Test getting the script results dao bean.
        */
        public void testGetScriptResultsBean&#40;&#41;
        &#123;
            _logger.info&#40;"getting a script results dao"&#41;;
            ApplicationContext ctx = Globals.getContext&#40;&#41;;
            ScriptResultsDAO dao = &#40;ScriptResultsDAO&#41;ctx.getBean&#40;"scriptResultsDAO"&#41;;
    
            assertTrue&#40;dao != null&#41;;
            assertTrue&#40;dao instanceof ScriptResultsDAO&#41;;
        &#125;
    everthing works fine if I don't try to inject the script results dao into the UploaderImpl class.
    The setter looks like:

    Code:
       /**
        * Set the ScriptResultsDAO.
        *
        * @pre  dao != null.
        * @post The script results dao for <code>this</code> has been
        *       set to <code>dao</code>.
        */
        public void setScriptResultsDAO&#40;ScriptResultsDAO dao&#41;
        &#123;
            assert&#40;dao != null&#41;;
            _scriptResultsDao = dao;
        &#125;
    any ideas what I'm doing wrong?

    thanks in advance for any help folks!

    Marty

  • #2
    Marty,

    I can't see anything immediately wrong. Can you post the rest of the stack trace for your error? Also, what version of Spring are you using?

    Rob

    Comment


    • #3
      Hey Rob,
      here's the full stack:

      Code:
           &#91;java&#93; 14&#58;11&#58;51,796 INFO  com.amtsybex.upload.aspects.Logging  &#58; <<< execution&#40;UploadProcess.testMethod&#40;&#41;&#41; &#58; 1
           &#91;java&#93; 14&#58;11&#58;51,796 INFO  .amtsybex.upload.domain.UploadProcess&#58; getting a script results dao
           &#91;java&#93; 14&#58;11&#58;52,567 INFO  com.amtsybex.upload.aspects.Logging  &#58; >>> execution&#40;ScriptResultsDAOImpl.initDao&#40;&#41;&#41; &#58; 
           &#91;java&#93; 14&#58;11&#58;52,567 INFO  com.amtsybex.upload.aspects.Logging  &#58; <<< execution&#40;ScriptResultsDAOImpl.initDao&#40;&#41;&#41; &#58; null
           &#91;java&#93; Exception in thread "main" java.lang.ExceptionInInitializerError
           &#91;java&#93; 	at java.lang.Class.forName0&#40;Native Method&#41;
           &#91;java&#93; 	at java.lang.Class.forName&#40;Class.java&#58;242&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.BeanDefinitionReaderUtils.createBeanDefinition&#40;BeanDefinitionReaderUtils.java&#58;60&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.parseBeanDefinition&#40;DefaultXmlBeanDefinitionParser.java&#58;306&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.parseBeanDefinition&#40;DefaultXmlBeanDefinitionParser.java&#58;274&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.parsePropertySubelement&#40;DefaultXmlBeanDefinitionParser.java&#58;530&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.getPropertyValue&#40;DefaultXmlBeanDefinitionParser.java&#58;521&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.parsePropertyElement&#40;DefaultXmlBeanDefinitionParser.java&#58;491&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.getPropertyValueSubElements&#40;DefaultXmlBeanDefinitionParser.java&#58;399&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.parseBeanDefinition&#40;DefaultXmlBeanDefinitionParser.java&#58;304&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.parseBeanDefinition&#40;DefaultXmlBeanDefinitionParser.java&#58;274&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.registerBeanDefinitions&#40;DefaultXmlBeanDefinitionParser.java&#58;186&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions&#40;XmlBeanDefinitionReader.java&#58;175&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions&#40;XmlBeanDefinitionReader.java&#58;133&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions&#40;AbstractBeanDefinitionReader.java&#58;99&#41;
           &#91;java&#93; 	at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions&#40;AbstractXmlApplicationContext.java&#58;102&#41;
           &#91;java&#93; 	at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions&#40;AbstractXmlApplicationContext.java&#58;70&#41;
           &#91;java&#93; 	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory&#40;AbstractRefreshableApplicationContext.java&#58;87&#41;
           &#91;java&#93; 	at org.springframework.context.support.AbstractApplicationContext.refresh&#40;AbstractApplicationContext.java&#58;262&#41;
           &#91;java&#93; 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;80&#41;
           &#91;java&#93; 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;65&#41;
           &#91;java&#93; 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;56&#41;
           &#91;java&#93; 	at com.amtsybex.upload.Globals.<clinit>&#40;Globals.java&#58;52&#41;
           &#91;java&#93; 	at com.amtsybex.upload.domain.UploadProcess.main&#40;UploadProcess.java&#58;71&#41;
           &#91;java&#93; Caused by&#58; org.springframework.beans.factory.BeanCreationException&#58; Error creating bean with name 'com.amtsybex.upload.domain.impl.UploaderImpl' defined in class path resource &#91;applicationContext.xml&#93;&#58; Error setting property values; nested exception is org.springframework.beans.PropertyAccessExceptionsException&#58; PropertyAccessExceptionsException &#40;1 errors&#41;; nested propertyAccessExceptions are&#58; &#91;org.springframework.beans.MethodInvocationException&#58; Property 'scriptResultsDAO' threw exception; nested exception is java.lang.NullPointerException&#58; null&#93;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues&#40;AbstractAutowireCapableBeanFactory.java&#58;879&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean&#40;AbstractAutowireCapableBeanFactory.java&#58;688&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean&#40;AbstractAutowireCapableBeanFactory.java&#58;325&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveInnerBeanDefinition&#40;AbstractAutowireCapableBeanFactory.java&#58;948&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveValueIfNecessary&#40;AbstractAutowireCapableBeanFactory.java&#58;909&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues&#40;AbstractAutowireCapableBeanFactory.java&#58;859&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean&#40;AbstractAutowireCapableBeanFactory.java&#58;688&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean&#40;AbstractAutowireCapableBeanFactory.java&#58;325&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean&#40;AbstractAutowireCapableBeanFactory.java&#58;260&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean&#40;AbstractBeanFactory.java&#58;221&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean&#40;AbstractBeanFactory.java&#58;145&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons&#40;DefaultListableBeanFactory.java&#58;285&#41;
           &#91;java&#93; 	at org.springframework.context.support.AbstractApplicationContext.refresh&#40;AbstractApplicationContext.java&#58;317&#41;
           &#91;java&#93; 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;80&#41;
           &#91;java&#93; 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;65&#41;
           &#91;java&#93; 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;56&#41;
           &#91;java&#93; 	at com.amtsybex.upload.domain.BaseDomainObject.<clinit>&#40;BaseDomainObject.java&#58;48&#41;
           &#91;java&#93; 	... 24 more
           &#91;java&#93; Caused by&#58; PropertyAccessExceptionsException &#40;1 errors&#41;
           &#91;java&#93; 	at org.springframework.beans.BeanWrapperImpl.setPropertyValues&#40;BeanWrapperImpl.java&#58;870&#41;
           &#91;java&#93; 	at org.springframework.beans.BeanWrapperImpl.setPropertyValues&#40;BeanWrapperImpl.java&#58;842&#41;
           &#91;java&#93; 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues&#40;AbstractAutowireCapableBeanFactory.java&#58;870&#41;
           &#91;java&#93; 	... 40 more
      using spring 1.1.5

      Comment


      • #4
        Marty,

        A couple of things to try:

        1. Does the property in question have a getter and if so is it public? If it is not public then you should change it to public or remove it.

        2. Try catching the PropertyAccessExceptionsException and looking at the inner information to see if it is more descriptive. Currently the information in the stack trace is not so useful

        Rob

        Comment


        • #5
          Rob,
          Cheers for the ideas... the one about removing the extra methods pushed me in the right direction and I got it sorted!
          Was doing daft things in the dao classes basically... had made them inherit from a BaseDAO class and (correct me if I'm wrong) then when trying to incorporate them into a transaction proxy means that they actually inherit from it instead. Hence the Nulls when trying to instantiate them and that.
          Is that correct?

          Cheers once more!

          Marty

          Comment


          • #6
            Marty,

            When you create a transactional proxy of a class, you end up with a dynamically created subclass of your class. If your DAOs have interfaces I would recommend that you configure the TransactionProxyFactoryBean to use the interface that way you'll get a proxy to the interface which is much less intrusive.

            Configure interfaces using the proxyInterfaces property.

            Rob

            Comment


            • #7
              ok sounds good... the dao's have interfaces.... say for example ScriptResultsDAO and then the derived ScriptResultsDAOImpl.

              Can you give me a wee code example?

              Marty

              Comment

              Working...
              X