nano_nano
nano_nano

Reputation: 12523

Servlet Autowire fails

I have trouble autowiring some beans in my servlet:

@WebServlet("/ScoreServlet")
public class ScoreServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

@Autowired
ScoreHandler mScoreHandler;
@Autowired
TransferAdapter mTransferAdapter;

ScoreCreator mScoreCreator;

public void init(ServletConfig config) throws ServletException{
    super.init(config);
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
      config.getServletContext());
}

if Spring tries to wire mScoreHandler I get this exception:

org.springframework.beans.factory.BeanCreationException: Injection of autowired dependencies failed for class [class de.bc.qz.server.servlet.ScoreServlet]; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: de.bc.qz.handler.score.ScoreHandler de.bc.qz.server.servlet.ScoreServlet.mScoreHandler; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [de.bc.qz.handler.score.ScoreHandler] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

My web.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>quiz-tomcat</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

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

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:META-INF/cmn-dao-spring.xml
            classpath*:META-INF/cmn-serv-spring.xml
        </param-value>
    </context-param>

    <servlet>
        <servlet-name>ScoreServlet</servlet-name>
        <servlet-class>de.bc.qz.server.servlet.ScoreServlet</servlet-class>
    </servlet>
</web-app>

This is the head of my ScoreHandler:

@Service
public class ScoreHandler {

@Autowired
private ScoreDao mScoreDao;

My JUnit-Test ScoreHandlerTest runs very well and without problems. I think it is an issue with Servlet and the Context.

The ScoreHandler is placed in its own project called cmn-server. This is the spring config(cmn-serv-spring.xml) of that jar:

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    <context:annotation-config />
    <import resource="cmn-dao-spring.xml" />
    <bean id="scoreHandler" class="de.bc.qz.handler.score.ScoreHandler"
        autowire="byName">
    </bean>
</beans>

Could you help me find the problem?

Upvotes: 1

Views: 1299

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280000

The error is hidden in

<param-value>
    classpath*:META-INF/cmn-dao-spring.xml
    classpath*:META-INF/cmn-serv-spring.xml
</param-value>

If you removed the *, you would get a

Caused by: java.io.FileNotFoundException: class path resource [cmn-serv-spring.xml] cannot be opened because it does not exist

Spring says the following about the classpath* prefix

This special prefix specifies that all classpath resources that match the given name must be obtained (internally, this essentially happens via a ClassLoader.getResources(...) call), and then merged to form the final application context definition.

If it doesn't find anything, it doesn't use (merge) any. This is explained here.

In your case, we can safely assume that META-INF is not on the classpath (and it probably shouldn't be) and therefore no files are found and no beans are generated.

I would declare a custom Spring context configuration file and add it to your classpath. Don't rely on other jars.

Upvotes: 2

Related Questions