Proper shutdown of JVM when launching from C++ - java

I'm launching JVM from C++ code via JNI. I have a problem that when just quitting my C++ process it seems some shutdown hooks from JVM are not run, and therefore some temp resources are still being around, that in my particular case prevents launching JVM next time I open a C++ process.
I tried jvm->DestroyJavaVM(), but after all my process windows were closed, I still could see the process running. What's the best wait to ensure that the JVM is shut down properly when launched via JNI?
Thanks!

First of all, jvm->DestroyJavaVM() won't return till all non-daemon jvm threads have stopped, it does nothing but waiting for them to stop, so you should stop them in java.
Secondly, System.exit will cause the whole process to be shut down.
So what you really need is check your java code that which thread is not stopped yet, for example the background message loop thread of the ui framework such as gwt or swing.

The easiest way is to call System.exit via JNI.

Related

Jython, stop script execution from inside of Java code

I'm using Jython as a scripting engine in my Java app.
I can run any Jython script from my Java app by calling pi.execfile(script_name). But the problem is that I also need a way to stop script execution manually from Java code. How can I stop it without modifying Jython script?
I'm running a script in a separate thread, so tried to interrupt it via
scriptRunningThread.interrupt(); and catch InterrupredException, but the thread just suspend and hang... Newly created threads will be hang too
Another way - to share a common object and make Jython script to check if user wants to quit.
The 3rd way is to run a separate process (console mode of my app) and kill it when ever STOP button being pressed. But I don't like this solution...
Any suggestions?
The best way is your second idea: to have the Jython script check for a termination flag and exit cleanly if the flag is set.
If you wanted to terminate the thread from another thread, you could call Thread.stop(), but that is generally a bad idea since it could cause your entire application to hang or otherwise misbehave in certain circumstances.

JNI - Java exits before native threads finish executing

I'm in the early stages of developing an API in C++, which I'm wrapping in Java using JNI. The native code creates a socket listener thread using WinAPI which should run indefinitely, thereby keeping the program open indefinitely (tested and works fine).
However, when I try to invoke this code in Java, the JVM still terminates when it reaches the end of main, ignoring the running thread. A little research has hinted that Java might think the thread is a daemon rather than a "user thread". But if that's the case, then I can't quite figure out how to convince Java that it actually is a user thread.
Does anyone have a clue about this?
You need to call AttachCurrentThread() for all your native threads, to ensure Java knows about them, so it will wait for them to finish.
Windows doesn't have daemon threads. The process exits when ExitProcess() is called or when the initial thread returns from the application's main function. (In principle, it will also exit if the last thread exits, but that can't be relied upon because Windows may create threads in your process that you don't know about.)
The Java runtime presumably waits for all of its own threads to exit (except for those that it considers daemon threads) before exiting the process. But your threads were created directly via the Win32 API, so Java doesn't know about them and therefore won't wait for them.
If your API wants to continue performing some task beyond the natural lifetime of the calling process, it should probably create a child process rather than a thread. (Or, if the API is Java-specific, it can presumably make use of JNI to ask that Java create the thread on its behalf, or to register the thread with Java.)

java server process not exiting cleanly

I have a init.d script which starts/stops a jruby based server running on java 8. It first does it the nice way with a kill and then after a while it falls back to a kill -9. I can see from my logs that the kill triggers the right shutdown hooks and eventually it calls System.exit(0). At this point the process should die, except it doesn't.
I've actually polled with a loop inside my init.d script whether the process still exists at that point (yes) and tried with a kill -QUIT to make it log a thread dump. The latter stops working after a few seconds but the process zombies along until I kill -9 it.
My question: how can I determine what is causing this? At least a thread dump would tell me what part of my code is blocking but it seems to be in a state where that no longer works and yet the process does not exit.
The suggestion by Joe to use Runtime.getRuntime().halt(int) works. Thanks

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. :)

Handling abnormal Java program exits

Suppose I have a Java application that opens a database connection. Normally I would add a connection.close() in a finally block, but this block wouldn't be executed in the case of a kill operation, or any other abnormal termination, would it? Are there any other precautions that I, as a programmer, can make in order to close the connection properly before the application exits?
You should look at the Runtime.addShutdownHook() method for Java (http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)). It allows you to add a hook that will be called when the virtual machine terminates. You can use it to call a cleanup routine.
That would be for a TERM signal though. A KILL signal will kill the process and not allow it to do any cleanup (because the KILL signal cannot be caught or ignored by the receiving process).
If something external kills your program, there's nothing you can do about it. Obviously they wanted to stop it, so how can you prevent them?
I was going to suggest a shutdown hook, but the Javadocs state:
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.
(emphasis mine)
Killing a program will eventually timeout a TCP stream from your program to your [Oracle|SQL Server|MySQL|PostgreSQL] server.
The server will see it and rollback any pending transactions.
You shouldn't need to call connection.close() on application shut-down, since all open files will be closed automatically by the operating system.
Also, the Connection's finalize() method should be run before application shut-down automatically (if the shut-down is normal, not ABORTed), and that should close the connection.
In any case, you can register shutdown-hooks, to do any clean-up you require (again, will be run in normal shutdown cases, not ABORTs).
When you really get killed (kill -9 on UNIX), you can not do anything against that.
A finally-block is the most you can do, see SO: In Java, is the “finally” block guaranteed to be called (in the main method)? for details.
Some level of abnormal termination is unavoidable. How would you catch the event of the power cable being pulled on the server?

Categories

Resources