Blockquote
I have a Java program with functionality that needs to be run periodically. However, I would like to be able to close the wrapper program (if you're a UNIX person, think Ctrl+C in the terminal window or SIGTERM) without any risk of interrupting the main program processes or threads that the wrapper would start.
At first I was thinking I should have my main program sleep for a certain interval after each round of processing. Then I figured that if the program needs to be closed and is manually interrupted by the user, it might be interrupted while it was processing data and the output files would be chopped or corrupted.
I'm thinking the best way is to write a wrapper program (probably also in Java) that would invoke the main program. If something closes the wrapper, I would like the spawned threads or program instances of my main program to remain open until they are ready to close properly. In addition, at most one instance of the main program should be running at any time.
Here's what I would like my wrapper to do (in pseudocode):
Every n minutes:
If an instance of the main program is running, do nothing
else spawn an instance of the main program.
On Close:
leave main program run to completion if it is running
Should I use the Java Runtime object/library to run my main program (effectively from the command line) or should I change my main program to implement Runnable and have the wrapper program spawn threads running my main program?
EDIT (possible solution?):
Currently I'm thinking of using the Java Runtime object to invoke the main program using the exec function (see http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html and http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html). To determine if the main program is already running I can just use the Process.exitValue() function. If it throws an IllegalThreadStateException then the main program is still running.
You can use a shutdown hook to perform an orderly shutdown when your application gets a SIGINT (Control-C): see Runtime.addShutdownHook(...).
However this doesn't deal with SIGKILL, JVM crashes, operating system crashes and hard power failures. Indeed, there is no way that an application can shut down cleanly in that kind of scenario. For that you need to design your application to periodically persist its state, using a robust persistence mechanism.
Create a new thread that has certain flags set in a static way. this thread will be run at the start of the main application, could be run/loaded from it.
Create a java event listener on the closing action of the program and regster your new thread in it. Whenever your program is closed this new thread will initiate other threads to come alive and do the final savings of the resources to perform one of the stated conditions above. your new process now will kill these threads one after another(whenever each on has done is job) until all the above conditions (flags) are met. when there is no other thread left, this new thread will kill itself, and the program is finished.
Related
When do I actually need call this method Runtime.getRuntime().addShutdownHook() and when or why I need to shutdown my application. Could anyone please explain me this by giving some example.
Thanks
As far as I know, I will explain this below. You can google it and find lot of information too.
addShutdownHook() will register some actions which is to be performed on a Program's termination. The program that you start ends in two ways:
the main thread (Root) ends its running context;
the program meets some unexpected situation, so it cannot proceed further.
If you add a ShutdownHook, the hook will start a thread that will start running at time of termination only. For example:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Running Shutdown Hook");
}
});
will print a Running Shutdown Hook at the time of program termination at any point. You might even call a System.exit(0).
For examples, you can google, there are enough of them. And the question 'When should you use this' is like asking 'What does catch do in a try-catch statement'.
You might have many situations like:
your program had created many temporary files in filesystem you want to delete it;
you need to send a distress signal to another process/machine before terminating;
execute any clean-up actions, logging or after-error actions on unexpected behaviours.
All this will be needed for some point of time.
For examples you can go in here Example 1 or Example 2
You only worry about shutdown hooks when you want something to happen when a shutdown occurs on the virtual machine.
From Javadoc:
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.
Thus, a shutdown hook is a initialized and unstarted thread that gets executed when a JVM shutdown occurs.
Popular examples of shutdown hooks exists in application servers (such as JBoss AS). When you press Ctrl+C, the JVM calls all the Runtime shutdown hooks registered (such as JBoss shutdown hooks) before exiting.
One case is, If you any daemon threads which needs to be stopped before your jvm shutdown (or) any other backend threads (mostly daemon threads) need to be gracefully exited, you will write shutdown hook and execute it using above code. Here is interesting discussion we had on SO couple of days ago. Shutdown hook
Unix daemon runs a script a loop, the script calls a java program: java {java_args} myClas.jar
The java program is heavy program with multiple threads.
The problem is very strange: First execution works as expected.
But the second execution is stuck some where and I can't find a reason (very hard to debug this).
Is there a possibility that when first execution is finished there are still not-cleaned resources or threads left from this execution?
If yes, is it possible to clean and kill everything right after process completes?
If by resources, you mean threads, then no. When the VM shuts down, everything on the heap, all threads, objects and monitors are disposed of. However if you're depending on the existence/absence of a file for locking or something similar, a deadlock is possible. Also, is it possible that the first process is still running when you launch the second one?
If your java process is stuck on the second run, you can attach jvisualvm to it and should be able to figure out where it's stuck.
I have a Swing interface, when I click on a button a thread is created at infinity (the genus while(true)...).
My question is: when I close the main process, will the created threads be closed automatically?
Depends on if the threads you've started are daemon threads or not, and how you close the main process.
Here's the relevant documentation from the standard library:
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.
So, if you shut down the main process by System.exit or by using jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) then all threads will die when you shut down.
If you simply let the main thread (the thread running public static void main) drop off the edge of the main method, then the threads will continue to run.
Yes, as long as it's not set up as a daemon thread. You can view instrumented JVM's using the jps tool:
jps -l
If I've got a Java program that can exit for various reasons, like:
because the main window, which is set to "exit on close", was closed
because there are some System.exit( 0 ) in the code
because there are no more window at all (and none was set to exit on close) but there's still several threads running then at one point there are only daemon threads running and hence the program exits.
And I've got a shutdown hook installed (which is running fine).
Is there any way to know, from my shutdown hook, what caused the Java program to exit?
(note that I'm not asking if it's a good idea or not to have System.exit(...) spread over the codebase: this is not what this question is about)
Basically I'd like to know if I'm forced myself to intercept every single possible JVM exit point and add infos there or if there's already a method allowing to do that.
You can add a SecurityManager which will be called on System exit (to determine if its allowed). You can save where this was called for later or deal with it in the SecurityManager.
Your shutdown hook will just run your runnable logic in a separate thread when the JVM is shutting down. You cant do anything more with this.
guys, I encounter a confusing issue! I want to invoke a executable JAR to compute PI from my main java applicaion using runtime.exec(), which create a new JVM for running the executable JAR. My issue is that when the PI computation is done, the JVM is still alive. my main java application has no idea whether PI computation is finished or not. And I also want when the PI computation is done, the JVM could be shutdown! How can I implement that! ThankS!!
When you call Runtime.exec() you will get a Process object back. You need to call waitFor() on this.
You will also need to capture the stdout/stderr streams (in separate threads to prevent blocking - see this answer for more info).
This all leaves aside why you're doing this in a separate JVM, and why you can't load the relevant classes into your current app and run the library locally.
To answer the second part of your question, the JVM always exits when no non-daemon threads are still running. Or in plainer speech, when your application is "done" and the main method exits without leaving any threads running in the background, the JVM will finish.
This is true regardless of whether you launch the Java process yourself from your desktop/command line, or fire it off via Runtime.exec() (which is broadly equivalent). So when your Pi calculation terminates it will shut down the JVM you spawned, and when your original program finishes then its JVM will also exit.
Though I agree completely with Brian here, I can't see the benefit in running a Java app as a separate process when you should be able to just run it in the original JVM (barring some really unusual environmental stuff such as setting niceness or processor affinity of the various processes).
check what the jar does when you run it standalone, maybe its waiting for input and therefor it will never exit