jaredready
jaredready

Reputation: 2698

Spring @Autowired Field - NoSuchBeanDefinitionException

I realize this question has been asked many times, but those answers don't seem to get me working.

The class which has the @Autowired field:

@Component
public class SpecialClaimsCaseManager {

    @Autowired
    private SpecialClaimsCaseRepositoryService<SpecialClaimsCaseDto> service;
    public SpecialClaimsCaseManager() {
    }

    public Collection<SpecialClaimsCase> findAll() {
        return convertToSpecialClaimsCase(service.findAll());
    }

The interface SpecialClaimsCaseRepositoryService

public interface SpecialClaimsCaseRepositoryService<C extends SpecialClaimsCaseDto> {
    //Some method signatures, not relevant

The implementation class (what should be injected)

@Service("specialClaimsCaseRepositoryService") 
public class SpecialClaimsCaseRepositoryServiceImpl implements SpecialClaimsCaseRepositoryService<SpecialClaimsCaseDto> {
    //Some method implementations, not relevant

mvcDispatcher.xml

<?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:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.0.xsd">

        <context:component-scan base-package="com.redacted.sch"/>

        <mvc:resources mapping="/resources/**" location="/resources/" />

        <mvc:annotation-driven />
        <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
           <property name="prefix" value="/WEB-INF/views/" />
           <property name="suffix" value=".jsp" />
        </bean>

    </beans>

web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>SpecialClaimsHandling</display-name>

    <!-- Spring Configuration Files -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            WEB-INF/application-security.xml
            classpath*:sch_model_spring.xml
        </param-value>
    </context-param>

    <!-- Spring Security Filters -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
             org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Spring Listeners -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- MVC Filter -->
    <servlet>
        <servlet-name>mvcDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvcDispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <!-- Session Configuration -->
    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>

</web-app>

sch_model_spring.xml (in another project)

<?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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

        <context:component-scan base-package="com.redacted.sch.model"/>

        <tx:annotation-driven />
        <tx:jta-transaction-manager />

        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
            <property name="url" value="redacted" />
            <property name="username" value="redacted" />
            <property name="password" value="redacted" />
        </bean>

        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
              <property name="persistenceUnitName" value="schManager" />
              <property name="dataSource" ref="dataSource" />
        </bean>

        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean> 
</beans>

Full stack trace (fpasted because it's pretty long) http://fpaste.org/116696/14049194/

So, as we can see, mvc:annotation-driven is enabled, and autowiring is enabled. If I understand this correctly (I might not, pretty new to Spring), this should be all I need. SpecialClaimsCaseRepositoryService is an interface, if that matters, though I don't think it should as this same @Autowiring worked fine in another class annotated with @Controller.

Thanks for any help!

Upvotes: 0

Views: 3715

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280141

You'll notice from your stack trace that the exception occurs in the process of initializing the root application context loaded by the ContextLoaderListener. That's taken from

<!-- Spring Configuration Files -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        WEB-INF/application-security.xml
        classpath*:sch_model_spring.xml
    </param-value>
</context-param>

In those two, you are scanning

<context:component-scan base-package="com.redacted.sch.model"/>

but not the com.redacted.sch.service... package that is required by one of the beans.

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.redacted.sch.service.SpecialClaimsCaseRepositoryService com.redacted.sch.model.SpecialClaimsCaseManager.specialClaimsCaseRepositoryService; 

In this case, xyz.model.SpecialClaimsCaseManager has an @Autowired field of type xyz.service.SpecialClaimsCaseRepositoryService, but no such bean exists.

Don't mix component-scanned folders between application contexts, those loaded by ContextLoaderListener vs DispatcherServlet. Refactor so that application beans are loaded by the ContextLoaderListener and controller-related beans are loaded by the DispatcherServlet.

Reading:

Upvotes: 3

Related Questions