Should threads have special design to be shutdown gracefully by Tomcat? - java

I have developed a multithreaded web application that runs in Tomcat.
But I cannot use
shutdown.bat
Tomcat didn't stop gracefully. In the debugger I saw that threads continue to run after shutdown command. Do I have to fix my application code to meet special requirements ?
Thanks.

... and to tie the other responses to the workings of Java Servlet environments;
if you don't declare your threads as daemon threads, the way to signal the server shutdown to the threads is to implement a ServletContextListener and configure it to your web application (web.xml). When Tomcat is shutting down, it will first shut down each application, which in turn will cause contextDestroyed() method of the listener to be called - and this is where you can signal your own threads that they should finish their work.

Any threads that are still running will keep the Java (Tomcat) process alive. Make sure all your threads exit. Once your threads exit, Tomcat will be able to shut down.
See the javadoc for Thread. Note the following:
The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

You need to cancel your threads, preferably by calling interrupt on them and making sure they are written in such a way that they respond to the interruption -- meaning, checking their interrupted flag and responding intelligently to InterruptedExceptions (not just eating them and continuing on).
The above advice assumes you don't want your threads to drop what they're doing immediately. If you are ok with that then make them daemons.

Related

Command to Interrupt a hung thread running in a java process without code changes

I've a java process running and unfortunately one thread inside the process is hung.
I found the Thread id which was hung using jstack, however I was unable to find any references on how to interrupt this thread using the id?
Is it possible to Interrupt/Stop a thread from console (or basically outside the process) by using the processId and ThreadId?
Any suggestions on how to tackle this?
PS : I don't want to kill the process as its just one thread which is hung. Also, neither do I want to make code changes to Stop/Interrupt the thread. I just want to kill it, so all its resources can be released.
There's no baked-in way to kill a thread within the JVM, at least not a deliberately implemented one.
Having said that, if you have started your JVM with the appropriate parameters, so that you can start a remote JMX session to it, you can actually suspend the thread and inject a RuntimeException into it, which will almost surely terminate it (unless you are doing something gnarly with RuntimeExceptions in it).
See this blogpost.
P.S. You would never start your JVM in production allowing rogue JMX connections though, and if you're not in production, I'd guess that the above approach is not of much help to you.

Using existing Thread for Java AWT

Is there a way to use a existing Thread (especially the main Thread) for AWT windows. I am currently opening a Frame which then handles everything and the main Thread is just paused and waits for the window to close. For me this seems like a (not very devastating) waste of resources, so I would appreciate only using the main Thread for AWT. Is there a good reason why this isn't done and if not, is there a way to do it?
Just let the main thread exit, there is no need to keep it paused and waiting around.
Threads can be marked as Daemon or not. The application only exits when every non-daemon thread has exited, in Java the Main thread doesn't really have any special significance beyond the fact it is started first.
The EDT thread is not a Daemon thread so it will keep the application alive by itself.
What is Daemon thread in Java?
Based on this documentation http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
moral of the story :
A Java program will wait for all non-daemon threads to finish first.
In your case you might wanna exit the main thread.
One paused thread (if it's even actually paused) isn't really a big deal. I suggest looking at your program in something like JProfiler, you'll be shocked at what's going on in the background.

How do I use swing in a shutdown hook?

Is there any possible way to add swing into a shutdown hook (that is, display a popup upon the VM shutting down)?
I realize that if I try to make a new JFrame, it will give me an error, as it tries to register a shutdown hook, which fails as the VM is already shutting down. I'm just wondering if there is in fact any way around this
You really shouldn't be doing this. From the Runtime.addShutdownHook specification:
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
...
Shutdown hooks run at a delicate time in the life cycle of a virtual machine and should therefore be coded defensively. They should, in particular, be written to be thread-safe and to avoid deadlocks insofar as possible. They should also not rely blindly upon services that may have registered their own shutdown hooks and therefore may themselves in the process of shutting down. Attempts to use other thread-based services such as the AWT event-dispatch thread, for example, may lead to deadlocks.
Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit. When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system may only allow a fixed amount of time in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook.
...
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.
Specific warnings here that suggest you not do this:
"Shutdown hooks should also finish their work quickly."
Relying on anything that might take a while to do its work, or blocking indefinitely on user-input like JOptionPane dialogs, is not what you should be doing in your shutdown hook.
"Attempts to use other thread-based services such as the AWT event-dispatch thread, for example, may lead to deadlocks"
Swing runs on-top of AWT, whose underlying event-dispatch thread may be in the process of shutting down, too. Trying to use Swing or AWT while shutting down can lead not only to dead locks but also may just not work at all, anyways.
"If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run"
There are no guarantees your user could even possibly get your message, since shutdown hooks are only guaranteed to run when it exits normally or terminated -- not when halted or aborted.
Shutdown hooks are supposed to execute as quickly as possible. That does not include waiting for a user to confirm a dialog. In any case you have no guarantee that the Swing event thread is still running.
You can't do this.
If there is, it won't help you.
The shutdown hooks are invoked asynchronously as part of the JVM shutdown, so a "confirm" dialog won't really confirm anything as you can't halt or reverse the shutdown process. Waiting for a user to make a decision is not the kind of action a shutdown hook is meant for. A shutdown hook in an interactive program does not make sense.
The real use case for shutdown hooks is:
for releasing resources and other housekeeping when the JVM shutsdown
It is also important to note the shut down hook wont always be run, for more see my answer here: How to shutdown java application correctly from C# one
Swing GUI must be done on Event Dispatch Thread, then
Create JDialog or JOptionPane on Initial Thread
Show Container
Call for Shutdown Hook
Simple way, but required end user action (close JDialog)
I'm not sure about your question, but I think its impossible to run or display a popup window when JVM is shutting down. Its like your trying to run while preparing to sleep? Just guessing. :)

Java kills daemon threads in applet reloads

I know that all daemon threads are supposed to be killed when no other non-daemon thread is alive.
I am developping applet which gets data from static objects. Those static objects are downloading some data from remote server in daemon thread. Several applets can access the same data so there is no sense in running thread for every applet.
Problem is when I reload page. Applets are reloading and they registers in those static objects and everything would be just fine except that then JVM kills daemon threads.
Maybe I explain step by step:
Applet is loading and it registers in static object which provides data.
Static object starts daemon thread.
Page reload.
Applet is beeing unloaded (stop() and destroy() are called)
New applet instance is beeing created and it registers in static object.
JVM throws ThreadDeath in daemon thread and communication stops.
In my mind, step 6 should be after 4 and before 5.
Am I missing something?
The workaround I developed is to sleep some time before registering in static object to let JVM kill daemons and then daemon is automaticaly created but it is only a workaround. Is there a some better solution?
Why don't you terminate the daemon thread in stop() or destroy() to make things more clear.
I would not encourage sharing background threads between applets, but if you insist, well you can do the following:
You can catch ThreadDeath by overriding Thread.setDefaultUncaughtExceptionHandler to be sure not to miss it.
You can then relaunch a new deamon thread from that handler to replace the killed one.
You should ensure you don't use synchronized on shared members in background threads, since your thread can be stopped while in the middle of a synchronized block, as documented by Thread.stop (the Java plugin uses Thread.stop to kill your threads).
Note that if you have at least 2 applets opened in 2 different tabs, reloading one does not make the JVM kill your thread.
The daemon flag does not seem to have any effect in applet environment.

How to implement thread pool that will automatically shutdown at end of execution?

I'm writing a Java client which could theoretically be used in a different environment: Java main(), in a servlet container, or via dependency injection.
The client implements internal connection thread pooling.
The problem with this approach is that users of the client that are unaware of the fact that an internal thread pool is implemented will see his or her application "hang" on shutdown. My users need to know to send a shutdown() message to the library.
I'm wondering if any other alternative approach could be taken that would, on one hand, allow me to start a thread pool for my connections; and, on the other hand, catch some event, perhaps a JVM event, that indicates the JVM is going down, which will allow me to call my shutdown() implementation.
Although you can add hooks, as was previous suggested, the problem you're still likely to have is the thread-pool still having active threads.
I believe that if you mark your individual threads as "daemons" (via Thread.setDaemon method) then the JVM will not keep alive if only daemon threads are left.
From the JavaDoc:
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
Using this, if your primary non-daemon thread is terminated, the JVM won't "hang-up" because of the other thread running, and this trigger your shutdown hooks without having to explicitly send terminate instructions to the various threads.
Runtime.getRuntime().addShutdownHook() would be the thing I would think of. http://blog.yohanliyanage.com/2010/10/know-the-jvm-2-shutdown-hooks/ has decent explanation. Does that help?
If the problem is that users of your code are not aware there is a thread pool to be shutdown, perhaps the solution is to make them aware of it? In the factory method or constructor for the relevant class, have the ExecutorService to use as an argument, so the caller is responsible for its lifecycle. That is, use depency injection to push policy upwards.

Categories

Resources