Spring attempting to #Autowire my dependencies twice - java

I have a Spring MVC application in which I'm trying to use #Autowired inside a class annotated with #Controller. In classes without the #Controller annotation, #Autowired works fine, as soon as I add the #Controller annotation, I get an enormous stacktrace at startup which mainly boils down to No qualifying bean of type [com.fasterxml.jackson.databind.ObjectMapper] found for dependency
I'm sensing that Spring is trying to autowire my dependency twice?
I'll get to the prove further down in my question ...
In my web.xml, I'm loading both my contextConfigLocation and DispatcherServlet:
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext.xml</param-value>
</context-param>
....
<servlet>
<servlet-name>ahpw-api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ahpw-api</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
....
webmvc-config.xml contains just the bare basics to allow me to open up a Jackson JSON API:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.ahpw.api" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<!-- Cookies Filter to set cookies on JSON AJAX responses -->
<mvc:interceptors>
<bean id="cookieInterceptor" class="com.ahpw.api.controller.COOKIEFilter"/>
</mvc:interceptors>
</beans>
In my applicationContext.xml I have the following:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<context:spring-configured/>
<context:component-scan base-package="com.ahpw.api" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Service" type="annotation"/>
</context:component-scan>
<!-- Setup Jackson instance -->
<bean id="jackson" class="com.fasterxml.jackson.databind.ObjectMapper" />
<!-- Setup RabbitMQ -->
<bean id="nativeConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
<property name="connectionTimeout" value="${rabbit.connection.timeout}"/>
<property name="requestedHeartbeat" value="${rabbit.heartbeat}"/>
</bean>
<rabbit:connection-factory
id="connectionFactory"
port="${rabbit.port}"
virtual-host="${rabbit.virtual}"
host="${rabbit.host}"
username="${rabbit.username}"
password="${rabbit.password}"
connection-factory="nativeConnectionFactory"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" reply-timeout="${rabbit.rpc.timeout}" />
</beans>
My class where the conflict is happening starts like this:
#Service
#Controller
#RequestMapping("/auth")
#JsonIgnoreProperties(ignoreUnknown = true)
public class AuthenticationController extends AbstractRPCPublisher<AuthenticationRequest, AuthenticationResponse> {
#Autowired
AmqpTemplate template;
#Autowired
ObjectMapper mapper;
If I remove #Controller, everything starts up fine, but obviously the request mapping of /auth stops working.
If I put #Controller back and duplicate the jackson bean and rabbitMQ goodies in webmvc-config.xml, it starts up without errors, but it means having two instances of each resource, a copy of the configs in both WEB-INF and META-INF, not desirable.
Is there a way to instantiate my controllers via webmvc-config.xml, but tell it to ignore #Autowired so that my applicationContext can take care of them and if so, will #Autowire function as normal?

You must define the ContextLoaderListener listener which will create the root context of your web application and load the contextConfigLocation define in the <context-param> tags:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Thus bean defined in the applicationContext.xml application context will be available to the webmvc-config.xml application context.
I don't know if it is a typo but the AuthenticationController class must not be annotated with #Service, #Controller is enough.

Related

Doesn't see a bean using Autowired annotation, nothing helps

I'm trying to autowire the Service in my Spring MVC app and it always fails! Tried everything from every question on the Internet but I couldn't find the answer. The problem is that Spring actually can't autowire field and says there is no such bean,
Tried everything, changing the code, configuration, etc. Maybe for now everything in my project is too messed up and I can't find the bug.
#Controller
public class ViewController {
#Autowired
private IUserService userService;
public void setUserService(IUserService userService) {
this.userService = userService;
}
}
#Component
#Service("userService")
public class UserServiceImpl implements IUserService {
private static final SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").
addAnnotatedClass(User.class).addAnnotatedClass(Restaurant.class).
buildSessionFactory();
public UserServiceImpl() {
}
}
dispatcher-servlet.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Step 3: Add support for component scanning -->
<context:component-scan base-package="com.springmvcdemo.Controller" />
<!-- Step 4: Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Step 5: Define Spring MVC view resolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>spring-mvc-demo</display-name>
<absolute-ordering />
<!-- Step 1: Configure Spring MVC Dispatcher Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- Step 2: Set up URL mapping for Spring MVC Dispatcher Servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="com.springmvcdemo.Services" />
</beans>
Error creating bean with name 'viewController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.springmvcdemo.Services.IUserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
So the problem is that the SessionFactory was being constructed in a static field of the service.
The class could be found, but there was some error creating the session factory which is why the error message contains "Instantiation of bean failed".
Moving the session factory to be managed by Spring and then injecting it was the way to go.

Spring MVC RequestMapping

I'm in the early stages of learning to use Spring MVC. I've created a controller and applied a RequestMapping annotation to it. When I run the project, the index page displays as expected at index.htm, but when I navigate to the URI that should be pointing to my controller, I get a 404 error, even though the controller seems to have been detected by Spring and started. Please help me understand what I am failing to grasp here:
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
Here is my applicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd>
<context:spring-configured/>
<context:component-scan base-package="org.blah.blah"/>
Here is my dispatcher-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
And, finally, here is my controller.
#Controller
#RequestMapping(value = "/hello")
public class Ctrl {
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public String hello(){
return "hello!";
}
}
EDIT: This is what my browser displays:
I was half-wrong in the comments to gravityplanx' answer.
When you specify a <mvc:annotation-driven /> in your servlet configuration, Spring registers a RequestMappingHandlerMapping bean which is meant to collect and map all your #Controller handler methods, ie. those annotated with #RequestMapping.
It does this by looking at all the beans in the current context. Remember that when you load a context with DispatcherServlet, call it the servlet context, if a context was loaded by a ContextLoaderListener, call it the root context, the root context is made a parent of the servlet context. By default, the RequestMappingHandlerMapping bean does not look at the root context, which is a parent of the servlet context.
In your case, the #Controller beans are declared implicitly in the root context (your applicationContext.xml) because of the <context:component-scan/> which scans classes annotated with
#Component or any of its specializations (#Controller for instance) and creates beans for them. So these beans are registered in the root context, where the RequestMappingHandlerMapping can't find them.
If instead you declare the <context:component-scan /> in the servlet context, then the #Controller (and other) beans are created in the servlet context where they are available to the RequestMappingHandlerMapping which can then register them to handle requests.
Note that <context:component-scan /> on its own doesn't do anything for the MVC stack. It needs further configuration, like <mvc:annotation-driven />. You should aim to specify packages that contain servlet specific beans in the servlet context and application wide beans in the root context.
Here's some literature:
What is the difference between ApplicationContext and WebApplicationContext in Spring MVC?
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
Your dispatcher servlet doesn't seem to be referenced correctly.
Replace:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
With:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>[insert the path to your dispatcher-servlet here]</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
And then move:
<context:spring-configured/>
<context:component-scan base-package="org.blah.blah"/>
From applicationContext to dispatcher-servlet

Can't #Autowire a bean into a controller - NoSuchBeanDefinitionException

I have a spring-mvc web app.
The following code has been simplified and sanitised to protect the guilty. The basic idea is that I have two separate context configuration files: one for MVC, the other for general config stuff.
When Spring goes to wire up the controller, I get:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.ConfigBean com.example.ConfigController.config; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.example.ConfigBean] 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)}
However, the following code from another servlet works just fine:
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
ConfigBean config = context.getBean(ConfigBean.class);
This suggests to me that the MVC component scanner can't see the config stuff for some reason. I've tried adding
<import resource="config.xml" />
to dispatcher-servlet.xml, but that made no difference. It feels wrong anyway, as I don't want two instances of the config beans. Even manually copying the ConfigBean declaration into dispatcher.xml doesn't fix my problem, which suggests to me I'm doing something really dumb. Any suggestions on what I might be missing?
My detailed configuration is as follows:
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
/WEB-INF/config.xml
</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
... Some other non-spring stuff ...
</web-app>
dispatcher-servlet.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:annotation-config />
<context:component-scan base-package="com.example" />
<mvc:annotation-driven />
</beans>
classpath:config.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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean class="com.example.ConfigBean">
<property name="foo" value="bar" />
</bean>
</beans>
ConfigController.java
package com.example;
import com.example.ConfigBean
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
#RequestMapping("/config")
public class ConfigController {
#Autowired
private ConfigBean config;
#RequestMapping(method=RequestMethod.GET)
public #ResponseBody ConfigBean getConfig() {
return config;
}
}
It might be because you have added /WEB-INF/dispatcher-servlet.xml to contextConfigLocation in context-param.
It is not required as the web-application context will ready the file based on the displater servlet name
From Spring Doc
Upon initialization of a DispatcherServlet, Spring MVC looks for a
file named [servlet-name]-servlet.xml in the WEB-INF directory of your
web application and creates the beans defined there, overriding the
definitions of any beans defined with the same name in the global
scope.
I think the autowiring is failing due to multiple instance of ConfigBean bean being present. The error message is slightly confusing. You get the same error if the bean is missing or if there are more than one instance.
The problem is with the component scan in the dispatcher-servlet.xml. Assuming that the ConfigBean class is also annotated with #Component or one of it's subtypes two instances will get created. Once for the bean definition in config.xml and once by component scanning.
To fix this you need to change the component-scan to ignore non-controller classes.
<context:component-scan user-default-filters='false'>
<context:include-filter annotation="org.springframework.stereotype.Controller"/>
</context:component-scan>
The lookup in the other servlet class is working because you are accessing the root application context directly.
This did turn out to be pretty dumb. The <context:annotation-config /> directive should have been in config.xml, not dispatcher-servlet.xml.
As I understand it, the annotation stuff is in the parent context, so that's where the directive belongs.

Spring singleton being called twice

getting some problem into my spring application.
I have very fairly simple spring beans, they are injected into various other spring beans. While debugging I found, they are being called twice, Constructor & #PostConstruct both called two times.
My application have no front end technology. Its simply for backend task related.
Spring Configuration
<?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:context="http://www.springframework.org/schema/context"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd">
<context:component-scan base-package="com.green.integration" />
<!-- ######################################################## -->
<!-- EXPOSING SPRING BEAN VIA HTTPINVOKER SPRING REMOTING -->
<!-- ######################################################## -->
<bean name="/switch"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="SwitchController" />
<property name="serviceInterface"
value="com.green.ISwitchController" />
</bean>
<!-- Load in application properties reference -->
<bean id="applicationProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:application.properties" />
</bean>
<bean id="mongo" class="com.mongodb.Mongo">
<constructor-arg value="${mongo.server}" />
<constructor-arg value="${mongo.port}" />
</bean>
<bean id="morphia" class="com.google.code.morphia.Morphia">
</bean>
</beans>
Spring Bean Class
#Repository
public class TransactionDAO extends BasicDAO<Transaction, ObjectId> {
private Datastore datastore;
#Autowired
public TransactionDAO(Mongo mongo, Morphia morphia) {
super(mongo, morphia, "itransact");
morphia.map(Transaction.class);
// TO USE MONGO WITHOUT SECURITY
this.datastore = morphia.createDatastore(mongo, "itransact");
logger.debug("***** CONNECTED TO MONGODB SUCCESSFULLY *****");
this.datastore.ensureIndexes();
// this.datastore.ensureCaps();
}
}
Constructor "TransactionDAO" is being called twice.
I tried to watch call stack trace by
Throwable t = new Throwable();
System.out.println(t.getStackTrace()[1].toString());
and each time it showed the following
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
I just figured out the problem and special thanks to #Juan Alberto who give me hint to the problem.
Description: Actually I was giving the one applicationContext.xml file for both contextListner and dispatcher servlet. So 1st bean was initializing for spring core and 2nd time for spring dispatcher.
I spilt the configuration now, into applicationContext.xml and applicationContext-dispatcher.xml which have only their relevant configurations and my beans are initializing once properly.
Problematic Configs
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>remoting</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
Solved Configs
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>remoting</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-dispatcher.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
Actually your issue is that you may be defining the beans in the dispatcher servlet and also your spring context, the dispatcher provides a different context but It (a sub context I think) of the main context so the right way to do things is having your main context scan your "model classes" and the dispatcher just only scan for the controllers.
I hope this helps you.

#Autowired doesn't work when using Jersey with Spring

I am trying to use Jersey with Spring. But for the life of me, I can't figure out why my Spring dependencies aren't being injected into my Rest Class.
Each time I try and invoke the autowired dependency I get NULL. Can anyone suggest why my dependency isn't being injected?
My Rest Class looks like this:
com.myapp.rest
#Component
#Scope("request")
#Path("/home")
public class ChartResource {
#Autowired
ChartService chartService;
#GET
#Path("/chart")
#Produces(APPLICATION_JSON)
public Bean getChart() {
return chartService.retrieveChart();
}
My web.xml file looks like this
<servlet>
<servlet-name>myapp</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.codehaus.jackson.jaxrs;com.myapp.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.codehaus.jackson.jaxrs</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
My applicationContext.xml is standard, and specifies the base package for component scanning:
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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">
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<context:component-scan base-package="com.myapp" />
</beans:beans>
Try adding
<context:annotation-config />
I'm not sure what you'll need to get Jersey's annotations to work, but #Autowired is a Spring annotation so you'll need to use the Spring version of <annotation-config> in order to get that to work properly.
Ok - silly question. My applicationContext wasn't being loaded and so it wasn't picking up the package I defined for component scanning!

Categories