Announcement Announcement Module
Collapse
No announcement yet.
Autowired constructor works in unit test and not when deployed Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Autowired constructor works in unit test and not when deployed

    I have the following class

    public class JdbcHelperService {

    private final DataSource dataSource;

    /**
    * Creates an instance of the service for the specified {@link DataSource}.
    *
    * @param dataSource the data source to use
    */
    @Autowired
    public JdbcHelperService(@Qualifier("dataSource") DataSource dataSource) {
    this.dataSource = dataSource;
    }

    // ...
    }

    Since the constructoris autowired, I declare the bean like this in my application context

    <bean id="jdbcHelperService" class="com.foo.bar.sql.JdbcHelperService"/>

    I am using the Spring test integration. Everything is working fine. However, when I deploy my app in JBoss, I get a deployment error (no matching constructor for JdbcHelperService). It seems that Spring tries to create my bean with the default constructor.

    What am I missing?

    Thx

  • #2
    Please provide more information. JBoss for example in standard configuration shares classes between application so it can be class loading issue, it can be also something with application context loading etc.

    Provide some info about Jboss instance, application context and exception.

    Comment


    • #3
      Originally posted by snicoll View Post
      Since the constructoris autowired, I declare the bean like this in my application context

      <bean id="jdbcHelperService" class="com.foo.bar.sql.JdbcHelperService"/>

      I am using the Spring test integration. Everything is working fine. However, when I deploy my app in JBoss, I get a deployment error (no matching constructor for JdbcHelperService). It seems that Spring tries to create my bean with the default constructor.

      What am I missing?

      Thx
      Runtime exception is correct behavior. Such configuration is not supposed to work. Consider the following example:

      Aggregated.java

      Code:
      package com.spring.ioc;
      
      public class Aggregated {
      }

      TestClass.java

      Code:
      package com.spring.ioc;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Component;
      
      @Component
      public class TestClass {
      
          private Aggregated field;
      
          @Autowired
          public TestClass(@Qualifier("a1") Aggregated aggregated) {
              field = aggregated;
          }
      
          public Aggregated getField() {
              return field;
          }
      }

      spring-config.xml

      HTML 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:tx="http://www.springframework.org/schema/tx"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:util="http://www.springframework.org/schema/util"
             xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
      
          <bean id="a1" class="com.spring.ioc.Aggregated"/>
          <bean id="a2" class="com.spring.ioc.Aggregated"/>
      
          <bean id="testClass" class="com.spring.ioc.TestClass"/>
      
      </beans>

      SpringStart.java

      Code:
      package com.spring;
      
      import com.spring.ioc.TestClass;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class SpringStart {
          public static void main(String[] args) throws Exception {
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
      
              TestClass testClass = (TestClass)context.getBean("testClass");
              System.out.println(testClass.getField());
          }
      }
      That example throws runtime exception all the time:
      Code:
      Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testClass' defined in class path resource [spring-config.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.spring.ioc.TestClass]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.spring.ioc.TestClass.<init>()
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:883)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:839)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
      	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
      	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
      	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
      	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
      	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
      	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
      	at com.spring.SpringStart.main(SpringStart.java:9)
      	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:597)
      	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
      Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.spring.ioc.TestClass]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.spring.ioc.TestClass.<init>()
      	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:58)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:877)
      	... 21 more
      Caused by: java.lang.NoSuchMethodException: com.spring.ioc.TestClass.<init>()
      	at java.lang.Class.getConstructor0(Class.java:2706)
      	at java.lang.Class.getDeclaredConstructor(Class.java:1985)
      	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:54)
      	... 22 more

      Correct way to configure the bean is to change context xml as follows:
      HTML 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:tx="http://www.springframework.org/schema/tx"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:util="http://www.springframework.org/schema/util"
             xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
      
          <context:component-scan base-package="com.spring.ioc"/>
      
          <bean id="a1" class="com.spring.ioc.Aggregated"/>
          <bean id="a2" class="com.spring.ioc.Aggregated"/>
      
      </beans>

      Comment


      • #4
        Oh right. So you're basically saying that Autowired constructor only works with classpath scanning, right?

        Good to know. I've not seen this in the doc.

        Thx!

        Comment


        • #5
          Originally posted by snicoll View Post
          Oh right. So you're basically saying that Autowired constructor only works with classpath scanning, right?

          Yes. However, it's possible to use schema-based configuration constructor autowiring facilities as well - 3.3.5. Autowiring collaborators.


          Originally posted by snicoll View Post
          Good to know. I've not seen this in the doc.

          Thx!
          Welcome.

          Comment

          Working...
          X