spring 3 scheduled task running 3 times - spring

I have a very simple method scheduled to run every 10 seconds like this:
#Component
public class SimpleTask {
#Scheduled(fixedRate=10000)
public void first() {
System.out.println("Simple Task " + new Date());
}
}
Config:
<task:annotation-driven executor="myExecutor" scheduler="myScheduler" />
<task:executor id="myExecutor" pool-size="5" />
<task:scheduler id="myScheduler" pool-size="10" />
My problem is that my method is being invoked 3 times every 10 seconds. It should be invoked just once. What am I doing wrong?
I use Spring Source ToolSuite with SpringSource tc Server 6.

I had this same problem. One of the causes is a bug in Spring 3.0.0. I upgraded to 3.0.5 and the repetition went down to only two.
The other cause was because my class that had the #Scheduled method was getting instantiated twice. This happened because the context config was getting loaded twice. In web.xml I was pointing my ContextLoaderListener and DispatcherServlet at the same context config file:
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring</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>1</load-on-startup>
</servlet>
...
WEB-INF/applicationContext.xml is the default context config for the ContextLoaderListener. So make sure that your ContextLoaderListener and your ServletDispatcher are using different context files. I ended up creating a /WEB-INF/spring-servlet.xml without any bean definitions and it worked flawlessly.

you are mixing annotations with configuration and I dont believe you need both
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-task-namespace
From Documentation
Note
Make sure that you are not initializing multiple instances of the same #Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use #Configurable on bean classes which are annotated with #Scheduled and registered as regular Spring beans with the container: You would get double initialization otherwise, once through the container and once through the #Configurable aspect, with the consequence of each #Scheduled method being invoked twice.

may be you load applicationContext multiple times ?

Related

Spring Data REST with Spring MVC: Adding RepositoryRestMvcConfiguration to existing DispatcherServlet

I have an existing Spring MVC Application with a DispatcherServlet and an XML based configuration.
Now I would like to integrate Spring Data REST but I dont know how to do this in a clean way. I added
<context:component-scan>...</context:component-scan>
so my RestControllers are found but I fail in adding a RepositoryRestMvcConfiguration config. I tried the annotation driven approach which doesnt work
#Configuration
public class RestConfiguration extends RepositoryRestMvcConfiguration {
...
}
and the
<bean class="com.mypackage.rest.RestConfiguration" />
approach is not working either.
I also tried the follwing in the web.xml
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mypackage.rest.RestConfiguration</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Strange thing is, a method annotated with #PostConstruct is called, but non of the configure* methods.
In the docs for Spring Data REST is a chapter where it is explained how to add a Spring Data REST to a Spring MVC application in code. It also says
The equivalent of the above in a standard web.xml will also work identically to this configuration if you are still in a servlet 2.5 environment.
How do you do this?
Fortunately, in Section 11.2 it is explained. Would have been nice to have a reference in Section 2.5 that points to Section 11.2 :-/
In Java, this would look like:
import org.springframework.context.annotation.Import;
import org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration;
#Configuration
#Import(RepositoryRestMvConfiguration.class)
public class MyApplicationConfiguration {
…
}
In XML this would look like:
<bean class="org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration"/>

About multiple containers in spring framework

In a typical Spring MVC project there two "containers": One created by ContextLoaderListener and the other created by DispatchServlet.
I want to know, are these really two IoC container instance?( I see two bean config files, one is root-context.xml the other is servlet-context.xml)
If there are 2 containers, then what's the relationship?
Can the beans declared in one container be used in the other?
From the Spring Official Website:
The interface org.springframework.context.ApplicationContext
represents the Spring IoC container and is responsible for
instantiating, configuring, and assembling the aforementioned beans.
The container gets its instructions on what objects to instantiate,
configure, and assemble by reading configuration metadata. The
configuration metadata is represented in XML, Java annotations, or
Java code.
Again from official Doc:
In the Web MVC framework, each DispatcherServlet has its own
WebApplicationContext, which inherits all the beans already defined in
the root WebApplicationContext. These inherited beans can be
overridden in the servlet-specific scope, and you can define new
scope-specific beans local to a given Servlet instance.
Now coming to your Question, as is stated here:
In Spring Web Applications, there are two types of container, each of
which is configured and initialized differently. One is the
“Application Context” and the other is the “Web Application Context”.
Lets first talk about the “Application Context”. Application Context
is the container initialized by a ContextLoaderListener or
ContextLoaderServlet defined in the web.xml and the configuration
would look something like this:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:*-context.xml</param-value>
</context-param>
In the above configuration, I am asking spring to load all files from
the classpath that match *-context.xml and create an Application
Context from it. This context might, for instance, contain components
such as middle-tier transactional services, data access objects, or
other objects that you might want to use (and re-use) across the
application. There will be one application context per application.
The other context is the “WebApplicationContext” which is the child
context of the application context. Each DispatcherServlet defined in
a Spring web application will have an associated
WebApplicationContext. The initialization of the WebApplicationContext
happens like this:
<servlet>
<servlet-name>platform-services</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:platform-services-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
You provide the name of the spring configuration file as a servlet
initialization parameter. What is important to remember here is that
the name of the XML must be of the form -servlet. xml.
In this example, the name of the servlet is platform-services
therefore the name of our XML must be platform-service-servlet.xml.
Whatever beans are available in the ApplicationContext can be referred
to from each WebApplicationContext. It is a best practice to keep a
clear separation between middle-tier services such as business logic
components and data access classes (that are typically defined in the
ApplicationContext) and web- related components such as controllers
and view resolvers (that are defined in the WebApplicationContext per
Dispatcher Servlet).
Check these links
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-basics
There aren't two separate containers created. Typically, you want spring to instantiate the object declared in the servlet-context.xml when the object is required. So, you map the servlet-context.xml configuration file to the Dispatcher Servlet i.e. you want to initialize the object when a request hits the dispatcher servlet.
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Where as, if you want to initialize the object and perform action when the context is being loaded you would declare the configuration file with in the context-param tags of your deployment descriptor.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
You could test this out by writing by declaring separate beans in the servlet-context.xml and root-context.xml and then, autowiring them in a custom Context Loader Listener class. You would find only the root-context instances are initialized and servlet-context beans are null.
ApplicationContext a registry of components (beans).
ApplicationContext defines the beans that are shared among all the servlets i.e. root context configuration for every web application.
spring*-servlet.xml defines the beans that are related WebApplicationContexts here DispatcherServlet.
Spring container can have either single or multiple WebApplicationContexts.
Spring MVC have atleast 2 container -
Application Context declared by
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
Servlet context declared by -
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
And a web application can define any number of DispatcherServlet's. Each servlet will operate in its own namespace, loading its own application context with mappings, handlers, etc. Only the root application context as loaded by ContextLoaderListener, if any, will be shared. Thus can have any number of child containers.

Getting singleton behavior. Spring contexts questions

I have been playing a bit with spring and have a question regarding getting singleton behavior on one of my classes. More specifically, I'm having a class called Cache which I would like to have singleton behavoir on. I'll start by posting the important parts of my actual code (an mdb, a servlet and a few xml files) and then elaborate on my question a bit more.
MessageReceiver.java
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class MessageReceiver implements MessageListener {
#Autowired
private Cache cache;
#Override
public void onMessage(Message msg) {
... do stuff with cache
}
beanRefContext.xml
<bean id="jar.context"
class="org.springframework.context.support.ClassPathXmlApplicationContext" >
<constructor-arg>
<list>
<value>spring-context.xml</value>
</list>
</constructor-arg>
</bean>
spring-context.xml
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="cache" class="com.company.myapp.cache.impl.CacheImpl"/>
web.xml
<context-param>
<param-name>parentContextKey</param-name>
<param-value>jar.context</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>com.company.myapp.servlet.Servlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
And in my servlet I inject a Cache instance with the following
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
cache = (Cache) ctx.getBean("cache");
Although the injection of a Cache instance is working both in the servlet and mdb, I'm not getting the same instance in both cases. I know that generally beans are not singletons across different contexts and my first question is if that also (or neccessarily have to) apply also in a parent child context setting.
My second question (in case the above code isnt easy to modify in order to get the behavior that I want) is if there is either a standard way to get singleton behavior across multiple contexts or if I somehow could make my mdb and servlet live in the same context. I have tried playing with the latter idea a bit but with no success (because of lack of knowledge I guess...).
Setting up a the cache in a parent context would solve this.
If you do not want to go that way, you could also implement an InitializingBean to instantiate the cache and save the singleton instance to a static field.

What can cause Spring IoC instantiate more than one instance of a singleton bean per WebApp?

I have a Spring based WebApp. In my application context, I have this bean defined:
<bean id="someSingleton" class="com.fake.SomeSingleton" scope="singleton"/>
I have the one Spring dispatch servlet definition and one class that has the #Controller annotation to which I auto-wired this bean, expecting Spring to only ever instantiating this class once. However, according to the following debug code, Spring is instantiating this class more than once:
private static final Semaphore SANITY_CHECK = new Semaphore(1);
public FakeSingleton(){
if(!SANITY_CHECK.tryAcquire()){
log.error("why?");
System.exit(-1);
else{
log.error("OK");
}
}
What can be the cause?
Note: I use spring 3.1.2.RELEASE
EDIT:
Thanks to the hints I was given, I found the culprit.
Apart from the DispatcherServlet, I also had a ContextLoaderListener in my web.xml. After removing it, SomeSingleton only got instantiated once.
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>FakeService</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>1</load-on-startup>
</servlet>
There are few possible reasons:
Your class is wrapped by some CGLIB proxy which causes the constructor to run twice (as opposed to #PostConstruct callback which always runs once per bean) - once for your class and once for inheriting proxy
more likely, your bean is being picked up by two contexts: main one and Spring MVC one. This is a poor practice and you should avoid it. Check out if your SomeSingleton class is not picked up by MVC dispatcher servlet context via some CLASSPATH scanning.
BTW in such a code it's safe to use simple AtomicInteger instead of Semaphore.
A singleton is once per context, not once-per-heat-death-of-the-universe.
Turn on logging and see why/if the entire app context is being created more than once.

spring aop and jersey classes

so in spring xml config, i define the following pointcut:
<aop:config>
<aop:aspect ref="metricsAdviceInterceptor">
<aop:around method="invoke" pointcut="#annotation(com.mycom.MetricsAdvice)"/>
</aop:aspect>
</aop:config>
The idea is to collect metrics on methods that have the "MetricsAdvice" annotation:
class SomeClass {
#MetricsAdvice
public void someMethod(...) { ... }
}
So this all works fine when i explicitly declare the beans in my spring config:
<bean id="someBean" class="com.mycom.SomeClass" />
But i want to be able to use this annotation on jersey code, and it doesn't work. Now, in the jersey config, one adds the below to web.xml. The idea is that you're telling jersey in which packages to find various rest services. Ie, it looks for classes in the packages: com.mycom.restservices.* and instantiates them. Presumably the instantiation of these beans is being done "differently", and thus aren't getting proxied:
<servlet>
<servlet-name>JerseyWebApplication</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<display-name>Jersey Servlet</display-name>
<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>
com.mycom.restservices.billing;
com.mycom.restservices.account;
org.codehaus.jackson.jaxrs
</param-value>
</init-param>
....
So what's "best practice" for trying to get these annotations to work on jersey beans?
Thx.
If all you need is to get rid of explicit bean declarations, you can use Spring classpath scanning feature instead of the Jersey one.
Just annotate your Jersey resources with #Component (or other similar annotations), and use <context:component-scan> to specify packages with these resources.
This way beans will be instantiated by Spring, and Spring AOP will work fine.
See also:
3.10 Classpath scanning and managed components

Resources