Results 1 to 5 of 5

Thread: Autowired constructor works in unit test and not when deployed

  1. #1

    Default 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. #2

    Default

    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.

  3. #3
    Join Date
    May 2007
    Location
    Saint Petersburg, Russian Federation
    Posts
    1,189

    Default

    Quote 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>

  4. #4

    Default

    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!

  5. #5
    Join Date
    May 2007
    Location
    Saint Petersburg, Russian Federation
    Posts
    1,189

    Default

    Quote 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.


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

    Thx!
    Welcome.

Posting Permissions

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