This question already has answers here:
How to run a background task in a servlet based web application?
(5 answers)
Closed 7 years ago.
I'm working on a web application which needs to clear expired cache elements now and then. I'd like to do this using the Quartz framework, and have a separate job to take part of this.
Now, I've used Quartz in other projects and usually schedule all jobs from a ServletContextListener using contextInitialised(ServletContextEvent sce) and contextDestroyed(ServletContextEvent sce). However, I've done it this way because a tutorial i once read did it that way.
I'm uncertain if I can just schedule the tasks from the servlet's init() and destroy() methods instead? I guess one could argue that I'm now mixing background tasks and servlets, and thus responsibilities, but I'd like to hear if there is a "best practice" on this?
First of all, usual disclaimer: you're not supposed to mess with threads in a Servlet container. So all the ways are by definition wrong (I suspect the right way would be calling curl from crontab).
ServletContextListener is the preferred method these days; Servlet's init() was an OK method back when ServletContextListener wasn't here. There are different problems with servlets, though: first of all, it may not be inited on startup (addressed by load-on-startup parameter); it can be unloaded just because servlet contained decided to do so (never saw in practice—but the spec says it can be).
Most important, though, is that it's a trick—and as any other trick, it makes little sense to the reader unless you document it carefully, or he knows well ahead that it's a trick. So if in doubt, avoid.
A servlet is not necessarily initialized when the webapp is deployed. It may be initialized lazily.
And you may have many servlets in a single webapp, so you might then wonder which servlet would be responsible of the scheduling.
A ServletContextListener is the right tool to use when something must be done at deployment and undeployment time.
Using contextInitialised and contextDestroyed methods of ServletContextListener looks perfectly correct for your case.
For example Spring Framework does exactly in the same way when initializing spring beans and scheduling tasks (org.springframework.web.context.ContextLoaderListener).
Also I would consider using some kind of abstraction for scheduling quartz tasks (for example mentioned Spring Framework).
Related
I have tried to look online, and found only few places that says spring is actually multi-threaded. Even those, seems to hint it simply uses a multi-threaded servlet container (as far as I understood, the single-threaded servlet containers are mostly deprecated, hence they all are multi-threaded these days).
I was hoping someone could clarify and validate that information; is the multi threading truly comes from servlet container and not spring?
And the more important question is, how do I initialize a per-thread data? As part of my database connection managing, I am using a library which requires me to initialize data in each thread.
Currently, I am checking a value on every call to that library, to know to initialize it.
But I prefer to simply initialize it every time a thread starts.
I believe it should be possible; After all, someone is creating those threads that keep calling my spring controllers.
p.s.
I am using the default servlet container in spring, which is Tomcat. I also tried doing a quick search for per-thread initialization and multi-threading in tomcat, but couldn't find any clear information on when a new thread actually spawn, or some information about a thread pool being used. I could be wrong though, and the multi threading is
I'm trying to create a web application for tomcat 7, but my problem is that I want to keep the whole backbone of the application running, so that my servlets can call the functions. Ex. I have my com.example.Main class which house all the instances to things like User managers and such. But instead of getting the main instance redefined on each servlet call, It would get defined once for all the servlets to use.
Best Regards,
- Roe
As far as I understand, you want a singleton. Check this answer for implementation.
But note that singletons are "evil". A more webapp approach is to not have it as singleton, but initialize it once in a ContextLoaderListener and then put it as a ServletContext attribute. Then each servlet can obtain it by getting it from the servlet context.
I agree with Bozho - you seem to be talking about a Singleton and I share his reservations about using them.
If you do implement it as a singleton, or use Bozho's suggested solution, it is important for you to understand that there will be only one instance of the class, potentially being used by many servlets at the same time. As a result, it is your responsibility to make sure that the class is thread safe, or your application will produce unreliable results.
I am creating a web application and in this I will be creating many services and executors to do some tasks.I have extended dispacter servlet and started executors or other threads in init method.Is this the right approach?
Now Suppose if any request comes and that executor or similar task executing thread dies after throwing Exception.
1.I suppose that it will affect other requests also.So what shall I do in such cases?
2.How can I create a monitor thread which will check if all critial tasks executing thread and executors are properly running?
3.Should I keep another backup executor prepared and deferred to takeover the failed executor in such situations?If so then how?
It is an old one, but maybe it would help someone :)
For ExecutorService there is a nice example on how to approach the problem in Codahale Metrics: https://github.com/dropwizard/metrics/blob/master/metrics-core/src/main/java/com/codahale/metrics/InstrumentedExecutorService.java
I did not find anything as good for the Spring AsyncTaskExecutors :/
Its been a while since I have used an Executor, are you using one of the built-in executors from Java, Spring, or are you rolling your own? Spring has a bunch, and I think Java gives you two or three concrete implementations.
Anyhow, I think the answer would be to roll some sort of monitoring service, like maybe something using JMX if you have that available. If you wanted to wire your Executors auto-magically you could use the ApplicationContextAware interface to get a reference to the ApplicationContext, which has a method called getBeansOfType(). If you want to take the more straight-forward approach, then you can simply write your monitoring service to inject the executors in there directly.
Another option would be to get an external monitoring framework/app. Something like Dynatrace, which attaches to the JVM process and monitors things or, if you don't mind switching app servers, SpringSource's tcServer, which has optional instrumented Spring JARs and provides a ton of out-of-the-box monitoring.
I'm looking at my Vaadin app running on a local tomcat server with JProfiler. This shows that every time I start up the server and run my application, there are 3 instances of my main Application class. If I close the application in the browser or even close the browser completely, there are 2 left. I've noticed that the Application's init() method gets called 3 times during startup, even though I never explicitly call it myself. I am using the Threadlocal pattern (but with InheritableThreadlocal).
It doesn't look normal to me, is there anything that can cause this kind of behaviour?
(Copied this question from my post on the vaadin forums)
From your description, I gather that Application is a class written by you (and not something supplied by Vaadin) and that you somehow save the instances of this class in a ThreadLocal.
This would explain the behavior that you're seeing: Tomcat will start several threads to handle client requests. For each thread, a new Application instance will be saved in the ThreadLocal.
Try the (evil) Singleton pattern or (better) dependency injection with the singleton scope instead.
If you use the singleton pattern, make sure you use the code under "Construct in multi-threaded applications" or you will get odd errors in Tomcat. This article on JavaWorld explains it in depth: Simply Singleton
EDIT Based on your feedback: The behavior your see is expected and correct. Tomcat uses threads to handle requests and it will pre-spawn a couple to be ready for business (in your case, it spawns three).
We have a need to run a housekeeping thread in an EJB3.0 container. We currently have a "TimerService" #Stateless EJB (necessary because it has has other #EJBs injected), which creates an interval EJB Timer when it's startTimer() method is called. There should only be one instance of this timer thread. The current solution involves calling startTimer() from the init() method of one of our servlets, where the servlet is forced to load at startup using in the web.xml, but that feels like coincidental behaviour instead of the right way to do things. We've already had a problem because someone else subclassed that servlet, which meant that init() was called twice, which meant two timer threads.
This feels like it's not an unusual requirement, so what's the proper way to do this, if anything? It seems to me like there ought to be a simple way to ask the container to start a thread when it starts up, without having to tie it to other resources in the container.
For EJB < 3.1 you are going to have to get application server specific or hackish. Since you mention you are using JBoss, you can use the #Management tag which has defined lifecycle methods.
I want to suggest 2 solutions.
1 The fix to your implementation.
make your servlet final. this will avoid subclassing. But the servlet still may be deployed twice. To avoid this create static boolean variable into the servlet. The init should check this variable. If it is false it turns it to true and continues. Otherwise it throws exception.
This is fast fix that you can do now.
but it is not a "right" solution. For example this will not work in clustered environment.
2 There are 2 "right" solutions.
2.1. use quartz
2.2. Implement timer using JCA. Connector is the only place in J2EE where you can legally use threads and timers.
I mentioned JCA in other context in this article:
http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html
You are welcome to view it and see a short code sample that can probably help you.
Does your app server support "startup beans"? I ask because in WebSphere Application Server, there is an option in the administrative console to set the server to fire "startup beans" on server start up. We use it for certain applications we have that require a lot of "heavy loading" and initializing, so that way we can minimize start up time for the end-user experience.
Here is a link to WAS 6 documention (old, I know, but still helpful). Startup beans
I know this is specific to IBM WebSphere, but perhaps your app server (if not WebSphere) has something similar to help you kick them off?