SCENARIO
I have a java application (uses Spring Integration for Listening on TCP/IP port).
I am using a few worker threads with an ExecuterService created with java.util.concurrent.Executors factory.
The main thread creates the worker threads and waits in a loop like follows
while(!shutdownRequested)
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I have a shutdown hook which stops the executer service and forces shutdown in case of timeout.
PROBLEM
This program does not terminate successfully on my machine (Windows 7). It leaves one thread listening on the tcp port and the process becomes inaccessible after that.
I cannot kill this process from task manager and get an "access denied" error.
It is interesting that this problem happens only my machine and does not affect any other windows 7 machines. On all other machines Control-C from console always stops the program successfully.
I have faced this problem in the past (with the same application) and the problem magically disappeared after I re-formatted and re-installed windows. (i know this was a bit too much!!)
The application worked perfectly for many months untill unfortunately i had to re-format my computer again recently for other reasons. After the re-formatting the problem has come back again.
This is very frustrating as I have to re-start windows every time I need to re-start this application as it cannot bind to the TCP port becuase of the zombie process litening on that port.
Any ideas what could be wrong with my setup?
You probably need to close() the socket.
This will cause the socket to throw a SocketException, and therefore stop blocking.
Related
I'm interested in different approaches to gracefully shutting down a Java command line program. Sending a kill signal is not an option.
I can think of a few different approaches.
Open a port and wait for a connection. When one is made, gracefully shutdown.
Watch for a file to be created, then shutdown.
Read some input from the terminal, such as "execute shutdown".
The third one is not ideal, since there is often program output pumped to the screen. The first one takes too much effort (I'm lazy). Do most programmers use the second option? If not, what else is possible/elegant/simple?
you can try something like this:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { /*
my shutdown code here
*/ }
});
edit:
the shutdown hook will not perform the shutting down of the app. instead, it gives the developer a way to perform any clean-up that he/she wishes at shutdown.
from the JavaDoc for Runtime (a good read if you are planning to use this method):
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt. ...
you could try to use Runtime.getRuntime().addShutdownHook() that should satisfy your requisite. In this way you can register an hook to do cleanups, in order to perfom a gracefull shutdown.
EDIT
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
public void addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
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.
The benefit of the second option - checking for a file - over the first - listening on a port - is that you have some possibility of security.
You can set the permissions on the directory where the file is created so that only appropriate users can close the program. If you listen on a port any user can connect to it.
If you wanted to go with the socket version, it is very simple to implement. Here's the code:
ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");
You could easily embed this code in a separate thread that you start with your program, and then have it modify global state to initiate shutdown.
The first two option is simple to implement. You could also use some JMX stuff (I don't know much about that). Tomcat uses the first approach and I applied 1 and 2 in two of my projects.
Consider having a JMX component. Then you can attach with JConsole either locally or over the network, and communicate with your component. Then the component can shut down the program properly.
With Java 6 u 10 or later, you can do the same with JVisualVM.
I would suggest to use the shutdown hook. It will allow your program do be controlled using standard OS tools. It also does not need any additional access to external resources (disk, ports, whatever).
I have an application runs in jboss 4.2.2 server with jdk 1.6. The program has bug in it that it doesn't set http connection timeout when it opens its the connection. So when the third party side has issues the connection is hanged forever which makes the thread hangs as well. And soon we are running out of thread. However, due to the release cycle we can't put a fix in immediately. I was wondering there is a way to terminate a network connection from outside the jvm? So the thread can be release back to the thread pool? I potentially has a lot of connection open to the same third party site so it is nice to figure out the problem connection and just kill that one.
Thanks,
While searching for a question of my own, I came across what seems to be a great tutorial on how to externally kill a thread.
http://www.rhcedan.com/2010/06/22/killing-a-java-thread/
You can grep the output of netstat and kill the connection using tcpkill, and run this using cron.
However this cannot be more than a very temporary solution.
This ServerFault Q & A may be relevant. It explains that tcpkill will only work if there is active traffic on the connection.
(This is because ... apparently ... tcpkill works by sending a TCP RESET packet. In order for this to work it needs to know the correct sequence number, and it can only figure this out by examining other packets for the session.)
While i am running my program i have svrSocket.accept() method..My program is automatically getting terminated when it reaches to svrSocket.accept() method.
Please suggest what needs to be done.
Here is what you need to provide before we can really help you.
Stacktraces for exceptions that accept() might be throwing. If this is a simple console application look for those in the console of your IDE. There is a separate window that it runs in and shows output like this.
Is the program truly terminating? accept() is a blocking call and blocks forever until another process connects to it through the socket. Have you tried running a client that connects to your server socket to see if it un blocks and continues to run? If you have to click the stop button, if multiple run windows are open then your program is simply blocked on the accept() call and it's working as designed.
Without example code or an error message for reference, according to the API, your application may not be catching one of the following exceptions:
IOException
SecurityException
SocketTimeoutException
IllegalBlockingModeException
Also, are you sure your application terminates? The only reason I ask is accept() blocks until a connection is made.
console java application. Someone kill java.exe process by Task Manager. How can I write to logs some information at this moment before application is terminated?
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) { ..... }
});
OR
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { ..... }
});
don't execute in such situation
This is not possible. Shutdown hooks will only be executed in an orderly shutdown:
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.
You can send another signal that will trigger an orderly shutdown like SIGINT. Killing a application should be the last resort after the application did not respond.
some practical solutions have already been suggested, but another is to ping-pong a "last status" message between 2 applications that monitor each other. When one dies, the other one writes the last received message to a log file. Users can't kill both processes quickly enough with Task Manager.
Some sort of solution is to write something to a log file all the time. This way you'll see whatever was the "last breath" of the Java program.
you might try to start java.exe via a small naive (e.g. c++) application using a CreateProcess (in windows ) this application will then continue running monitoring the java process handle. if the java process is gone it can log it.
Give your users an orderly way to shut down the system, and tell them to stop using Task Manager to do so.
I am using Socket communication in one of my Java applications.As I know if the program meets any abnormal termination the listening ports does not get closed and the program cannot be started back because it reports "Port already open.."
Do I have anyway to handle this problem? What is the general way used to handle this matter?
It sounds like your program is listening on a socket. Normally, when your program exits the OS closes all sockets that might be open (including listening sockets). However, for listening sockets the OS normally reserves the port for some time (several minutes) after your program exits so it can handle any outstanding connection attempts. You may notice that if you shut down your program abnormally, then come back some time later it will start up just fine.
If you want to avoid this delay time, you can use setsockopt() to configure the socket with the SO_REUSEADDR option. This tells the OS that you know it's OK to reuse the same address, and you won't run into this problem.
You can set this option in Java by using the ServerSocket.setReuseAddress(true) method.
You want to set the SO_REUSEADDR flag on the socket.
See setReuseAddress().
The operating system should handle things such as that automatically, when the JVM process has ended. There might be a short delay before the port is closed, though.
As mentioned in the Handling abnormal Java program exits, you could setup a Runtime.addShutdownHook() method to deals with any special case, if it really needs an explicit operation.