Executor thread keeps running after hot deploy - java

Is there any way to know when a war is being hot deployed so I can shutdown the old executor that is running scheduled tasks? I'm using jboss 6 and I have a scheduled thread pool that is updating data periodically in the background. When I hot deploy that thread pool is not shutdown and new starts up so I have multiple scheduled thread pools.
Thanks for any input.

Yes, but it depends on where you start your Executor and which technology you use:
in ServletContextListener: start Executor in contextInitialized() and shut it down in contextDestroyed().
in servlet, start Executor in init(), shut it down with destroy()
in EJB/Spring bean: start in method annotated with #PostConstruct, shutdown in #PreDestroy.

Sure. It depends on how do you run this thread. If for example you are running it from sevlet use servlet's destroy() method to stop it. If you are using Spring use lifecicle of its Application context.

Related

How to handle Spring context shutdown when beans that are already destroyed are needed for the shutdown tasks

I have a large and complex Spring application with many beans and services. During the shutdown process, one of the beans in particular (a cache service bean) is needed by several other beans to accomplish their shutdown tasks. The problem I'm running into is beans cannot access the required service, because it is in the process of being shutdown as well. I get an exception that a singleton instance of the cache service bean cannot be created while it's in the process of being destroyed.
One solution I've tried is creating a handler that implements ApplicationListener<ContextClosedEvent>. This intercepts the context close event right as it's fired, before the beans are destroyed. In this handler I'm sending emails and calling the close/shutdown logic on the beans that in turn depend on the cache service. The problem seems to be that the shutdown process continues asynchronously while my logic is trying to execute and the required cache service bean is already destroyed by the time it's needed.
The only other solution that I can see is to implement a #PreDestroy method in the cache service itself which performs the shutdown tasks contained in the other beans. This is not optimal, since it tightly couples the cache service logic to other unrelated parts of the application.
Is there a way to "get in front" of the context close event to complete these tasks before any beans are destroyed? The application is running in a Tomcat container. Is there a way to intercept the stop signal from Tomcat and implement a custom handler where I can perform shutdown tasks, then manually call context.close() to begin the Spring shutdown process?

stopping threads gracefully

I am using ScheduledExecutorService for scheduling a thread. I wonder what happens when JBoss is shut down? Does it kill all the threads that are started within the server, including the the one I scheduled? Do I have to do it manually using ScheduledFuture, and cancel the thread when ServletContext is destroyed?
There are two methods:
java.util.concurrent.ExecutorService.shutdown()
java.util.concurrent.ExecutorService.shutdownNow()
JBoss won't call any of these unless you do it in method which will be called upon shutdown. For web applications you have the chance to do it in javax.servlet.ServletContextListener.contextDestroyed(ServletContextEvent).
Of course this is the JavaEE/Servlets way. You can hide it by using e.g. Spring Framework. By creating org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler you'll get shutting down for free (this class implements org.springframework.beans.factory.DisposableBean). See the details here.

Call method after JBoss deploy

I want to have some method run, only after my WAR has been deployed to JBoss.
The problem: Currently I am using #PostConstruct to load saved schedules from the DB. The problem is that I am creating instances of the Schedulers from this method, which in turn is starting the Quartz schedulers, which is stopping JBoss from completing the deploy.
If there are no schedules to load, my WAR deploys fine, but if there are schedules they are causing the deploy to fail, because JBoss is "waiting" for the schedules to actually complete.
Is there some way to delay the method call until after it is fully deployed?
Or alternatively, is it possible to make Async calls on the Server (from the Server code)?
Java EE specification heavily refrain any thread manipulation outside facility provided by the application server.
You shouldn't in any case use a container manged thread in an infinite loop; the container expect the thread to be returned. Thread creation can still be done without too much collateral damage (if you don't put several apps on the server as the container won't be able to manage the resources between all the applications) but the any container thread must be returned.
In the new Jboss 7 there is some Java EE scheduling facilities (#Scheduling and timer, with possible persistent timer). A quick search show some example how to run Quartz in JBoss 7: How to enable Quartz scheduling in Jboss AS 7.0?
In older JBoss more advanced integration exist (JCA integration is the only standard way to get finer thread management). Use google to find them.
Wouldn't the simple ServletContextListener solve the problem for you? Just implement whatever you need in contextInitialized method.
In JBoss 7, there is a management api.
Maybe you can use it to check if the server is started (with a singleton and a TimerService).
Sample code:
ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getByName("localhost"), 9999);
ModelNode op = new ModelNode();
op.get(ClientConstants.OP).set("read-attribute");
op.get(ClientConstants.NAME).set("server-state");
ModelNode returnVal = client.execute(op);
if(StringUtils.equals(returnVal.get("result").toString(), "\"running\"")){
LOGGER.info("Server running, init start actions");
timer.cancel();
}else{
LOGGER.info("Server not running, wait");
}

Quartz on a webapp - scheduler does not stop

I have a webapp running on weblogic that runs a Scheduler on a ServletContextListener.
The problem is the scheduler runs indefinitely, so even if i stop the webapp or redeploy the scheduler keeps running.
I should be able to stop the scheduler on contextDestroyed, but I don't have the instance. I've seen a couple of websites recommending this aproach to the problem, but they all have shedulers running a defined number of times.
Quartz comes with a servlet specifically for starting & stopping the scheduler on application startup and shutdown simply add the following to your web.xml:
<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
If you want to shutdown without waiting for the executing jobs to finish use:
scheduler.shutdown(false);
Check this page for more info.
Upon application shutdown you must call
scheduler.shutdown();
Sometimes you have to do a Thread.sleep(1000); to let it shut down properly aswell.
Do this in a ContextLoad listener or other shutdown hook that you have.
To get the instance depends on how you have set up quartz, but the default scheduler can be obtained like this:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
See http://www.quartz-scheduler.org/docs/1.x/quick_start_guide.html for more information

Shutting down a TaskExecutor in a web application when the web server is shutdown

I have a web application that makes use of a Spring TaskExecutor. The task executor is started when the web application is loaded for the first time and the thread runs the entire life of the web application. Ever since I added this thread to the application, Oracle Application Server will no longer shutdown gracefully. My guess is that OAS is not shutting down because I am not gracefully shutting down the task executor thread anywhere in the code. Where would the best place be to shutdown the task executor in a web application? I am using Java 5 with Spring 2.5.6.
Here is the task executor that I am using:
<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
SimpleAsyncTaskExecutor has no meaningful state, it does not require shutting down gracefully. Also, I'm not sure what you mean by "the thread runs the entire life of the web application" - which thread are you referring to?
However, the threads that it spawns may be preventing your server from shutting down. SimpleAsyncTaskExecutor uses a ThreadFactory to create its threads, and by default threads that are created are not daemon threads, and so any spawned threads which are still executing when the shutdown is initiated will continue, and the server will only terminate when all of those spawned threads are finished.
As a solution, I suggest using a ThreadPoolTaskExecutor in preference to the SimpleAsyncTaskExecutor. This has a boolean property which controls what happens when a shutdown occurs, and it can force the termination of the thread pool if required.
If you still want to use SimpleAsyncTaskExecutor, then you could inject it with a custom ThreadFactory which creates deamon threads. This will allow the server to shutdown regardless of the state of those spawned threads. This might be dangerous, though, if those threads could leave resources in an unstable state.
Spring provides a bean-friendly implementation of ThreadFactory (CustomizableThreadFactory) which you can inject into the SimpleAsyncTaskExecutor, setting the daemon property to false.
Typically web aplications can react to container shutdown via a ServletContextListener. Implement one and use it to shut down your Executor. Ideally you should couple that with a proper shutdown of the whole Spring lifecycle. I vaguely remember that Spring had something ready-made for that purpose, so it's probably a good idea to check there as well.
You can use the #PreDestroy annotation:
#PreDestroy
protected void shutDown() {
taskExecutor.shutdown();
}

Categories