Announcement Announcement Module
Collapse
No announcement yet.
Configurable Autowired NullPointerException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Configurable Autowired NullPointerException

    Hello to all,

    I have a GenericServlet class annotated with @Configurable which has field called dao which autowired by spring but it does not get autowired properly rather than throw nullpointerexception.


    Code:
    @Configurable
    public class GenericServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
        
    	@Autowired
    	@Qualifier("genericDaoImpl")
    	private GenericDAO dao;
    }
    Code:
    @Repository
    @Qualifier("genericDaoImpl")
    @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.DEFAULT, rollbackFor={Exception.class, SQLException.class, DataAccessException.class}, timeout=9999)
    public class GenericDAOImpl implements GenericDAO {
    
    	@Autowired
    	@Qualifier("jdbcTemplate")
    	private JdbcTemplate jdbcDao;
    }

    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:p="http://www.springframework.org/schema/p"
    
    	<!-- Enable Spring Application Context -->
    	<context:spring-configured />
    		
    	<!-- Enable @Required @Autowired @PreDestroy @PostConstruct @Resource -->
    	<context:annotation-config />
    	
    	<!-- Scan class file in class path for annotated component -> @Component, @Repository, @Service, and @Controller  -->
    	<context:component-scan base-package="com.breeze.bis.core.service.jdbcTemplate" />
    
    	<!-- Enable load time weaving for @Configurable -->
    	<context:load-time-weaver aspectj-weaving="autodetect" />
    	
    	<!-- Alternate method to enable @Autowired -->
    	<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    
    	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/vbossdb" />
    		<property name="driverClass" value="com.mysql.jdbc.Driver" />
    		<property name="user" value="root" />
    		<property name="password" value="root" />
    	</bean>
    	
    	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    		<constructor-arg type="javax.sql.DataSource" ref="dataSource"></constructor-arg>
    	</bean>
    
    	<bean id="genericDaoImpl" class="com.breeze.bis.core.service.jdbcTemplate.GenericDAOImpl">
    		<property name="jdbcDao" ref="jdbcTemplate"></property>	
    	</bean>
    		
    	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property> 
    	</bean>
    	
    	<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
    		<property name="configLocation" value="WEB-INF/ehcache.xml"></property>
    		<property name="shared" value="true"></property>
    	</bean>
    
    </beans>

    Please let me know what wrong with this configuration.

    Thanks.

  • #2
    Please help.

    Comment


    • #3
      For starters cleanup your configuration file there is a lot of duplication going on..

      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:p="http://www.springframework.org/schema/p"
      
      	<!-- Enable Spring Application Context -->
      	<context:spring-configured />
      		
      	<!-- Enable @Required @Autowired @PreDestroy @PostConstruct @Resource -->
      	<context:annotation-config /> <!-- Already implied by component-scan -->
      	
      	<!-- Scan class file in class path for annotated component -> @Component, @Repository, @Service, and @Controller  -->
      	<context:component-scan base-package="com.breeze.bis.core.service.jdbcTemplate" />
      
      	<!-- Enable load time weaving for @Configurable -->
      	<context:load-time-weaver aspectj-weaving="autodetect" />
      	
      	<!-- Alternate method to enable @Autowired -->
      	<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
       <!-- Already implied by component-scan AND annotation-config -->
      
      	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
      		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/vbossdb" />
      		<property name="driverClass" value="com.mysql.jdbc.Driver" />
      		<property name="user" value="root" />
      		<property name="password" value="root" />
      	</bean>
      	
      	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
      		<constructor-arg type="javax.sql.DataSource" ref="dataSource"></constructor-arg>
      	</bean>
      
      	<bean id="genericDaoImpl" class="com.breeze.bis.core.service.jdbcTemplate.GenericDAOImpl">
      		<property name="jdbcDao" ref="jdbcTemplate"></property>	
      	</bean> <!-- Already using Component-Scan duplicate bean definition -->
      		
      	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      		<property name="dataSource" ref="dataSource"></property> 
      	</bean>
      	
      	<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
      		<property name="configLocation" value="WEB-INF/ehcache.xml"></property>
      		<property name="shared" value="true"></property>
      	</bean>
      
      </beans>
      This config must be loaded by the ContextLoaderListener for @Configurable in servlets to work, also if it works depends on y our container it might be that it doesn't work and that it required additional configuration. For more information I suggest the reference guide chapter on loadtime weavnig in containers.

      Comment


      • #4
        Yes, I had clean up the config. The Config was loaded by ContextLoaderListener. I thought the @configurable is relate to spring and not container problem. I had enable logging and how to diagnose the problem which DI(Configurable, Autowired) not working. No stacktrace or log.

        I using TomcatInstrumentableClassLoader which put inside the Tomcat\lib directory and context.xml in Meta-INF Folder.

        15:49:12,351 INFO DefaultContextLoadTimeWeaver:89 - Using a reflective load-time weaver for class loader: org.springframework.instrument.classloading.tomcat .TomcatInstrumentableClassLoader
        15:49:13,033 INFO DefaultListableBeanFactory:577 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultL istableBeanFactory@1df304: defining beans [org.springframework.context.config.internalBeanCon figurerAspect,genericDAOImpl,org.springframework.c ontext.annotation.internalConfigurationAnnotationP rocessor,org.springframework.context.annotation.in ternalAutowiredAnnotationProcessor,org.springframe work.context.annotation.internalRequiredAnnotation Processor,org.springframework.context.annotation.i nternalCommonAnnotationProcessor,org.springframewo rk.context.weaving.AspectJWeavingEnabler#0,loadTim eWeaver,org.springframework.aop.config.internalAut oProxyCreator,org.springframework.transaction.anno tation.AnnotationTransactionAttributeSource#0,org. springframework.transaction.interceptor.Transactio nInterceptor#0,org.springframework.transaction.con fig.internalTransactionAdvisor,org.springframework .cache.annotation.AnnotationCacheOperationSource#0 ,org.springframework.cache.interceptor.CacheInterc eptor#0,org.springframework.cache.config.internalC acheAdvisor,dataSource,jdbcTemplate,transactionMan ager,ehcache,cacheManager,org.springframework.cont ext.annotation.ConfigurationClassPostProcessor.imp ortAwareProcessor]; root of factory hierarchy
        15:49:13,338 INFO MLog:80 - MLog clients using log4j logging.
        <Context path="/myWebApp" docBase="/my/webApp/location">
        <Loader loaderClass="org.springframework.instrument.classl oading.tomcat.TomcatInstrumentableClassLoader"
        useSystemClassLoaderAsParent="false"/>
        </Context>

        I change the Autowired using setter in GenericServlet and the setter is not even get called.
        Last edited by peterwkc; Jan 10th, 2013, 03:53 AM.

        Comment


        • #5
          As mentioned read the reference guide some containers need additional configuration (Tomcat for instance) to make loadtimeweaving work.

          Comment


          • #6
            Originally posted by Marten Deinum View Post
            As mentioned read the reference guide some containers need additional configuration (Tomcat for instance) to make loadtimeweaving work.
            I using TomcatInstrumentableClassLoader (Spring-Instrument-Tomcat-3.1.2.jar) which put inside the Tomcat\lib directory and context.xml in Meta-INF Folder.

            <Context path="/myWebApp" docBase="/my/webApp/location">
            <Loader loaderClass="org.springframework.instrument.classl oading.tomcat.TomcatInstrumentableClassLoader"/>
            </Context>

            What are the additional configuration for load time weavering since the servlet can be loaded by the TomcatInstrumentableClassLoader.

            Comment


            • #7
              I should have read your logging output which clearly indicates that the loadtimeweaver is already beeing used.

              The servlet is in the same application as the loadtimeweaver stuff? As it will only work in the same application. The only thing I can think of is that either the servlet is already being loaded before loadtimeweaving can be applied or it is in a different classloader.

              Also make sure that the context.xml actually matches your web application apparently you have blindly copy/pasted from the reference guide.

              Comment


              • #8
                Originally posted by Marten Deinum View Post
                I should have read your logging output which clearly indicates that the loadtimeweaver is already beeing used.

                The servlet is in the same application as the loadtimeweaver stuff? As it will only work in the same application. The only thing I can think of is that either the servlet is already being loaded before loadtimeweaving can be applied or it is in a different classloader.

                Also make sure that the context.xml actually matches your web application apparently you have blindly copy/pasted from the reference guide.
                The servlet is locate at same project with the loadtimeweaver bean in Spring applicationContext.xml. How to ensure the servlet is load by loadtimeweaving and not before or in different classloader (default tomcat class loader) ? There is contextLoaderLListener configured already. Any thing i can check or diagnose or logging ?

                This is my context.xml.

                <?xml version='1.0' encoding='utf-8'?>
                <Context path="/BISDAO" docBase="${catalina.home}/webapps/BISDAO">
                <Loader loaderClass="org.springframework.instrument.classl oading.tomcat.TomcatInstrumentableClassLoader" />
                </Context>
                Please help. Thanks in advance.

                Comment


                • #9
                  Perhaps I should check which class loader load the GenericServlet.

                  ClassLoader cls = GenericServlet.class.getClassLoader();
                  System.out.println(cls);

                  org.springframework.instrument.classloading.tomcat .TomcatInstrumentableClassLoader
                  WebappClassLoader
                  context: /BISDAO
                  delegate: false
                  repositories:
                  /WEB-INF/classes/
                  ----------> Parent Classloader:
                  org.apache.catalina.loader.StandardClassLoader@125 fefa


                  ApplicationContext ctx = new FileSystemXmlApplicationContext ("D:\\work\\vboss\\BISDAO\\WebContent\\WEB-INF\\applicationContext.xml");
                  TestAutowired bean = (TestAutowired) ctx.getBean("testAutoWired");
                  GenericDAO dao = bean.getJdbcDAO();
                  In this case the dao is not null, this clearly indicate is a load time weaving problem.
                  Last edited by peterwkc; Jan 13th, 2013, 08:45 PM.

                  Comment


                  • #10
                    Please help.

                    Comment

                    Working...
                    X