How can I close my software in a safe way? - java

Up to now I used my application as a stand alone product. So, when user pressed "Stop" button I called System.exit(0); and it was fine.
Now my application will be called (in a programmatic way) from another program. So, I afraid that System.exit(0); will kill not only my process but also the external software which started my program.
So, what is the correct way to shutdown my application if a corresponding request from an external software is received? My application is an GUI application. So, I want to close the window but I also want to close all processes performed by my program.
ADDED:
To be more specific, I want to close all threads started by my program. My program does not start any OS process or any other program.

If the threads you've launched are still processing then calling System.exit(0) will cause them to be killed. In some cases, this can leave your application in an inconsistent state. Imagine that the thread was saving a file for example.
You should ensure that the your threads are all 'happy' to die before calling System.exit.
One technique you can use for this with long running threads is poisoning. To do this you send the threads a message that they should now die gracefully - i.e. a poson message. Once they have all died, it is safe to call System.exit(0) to terminate the Swing event handling thread.
There a loads of different ways of implementing poisoning, you could just set a global flag variable that the threads check to see if they've been poisoned, or you could use the Java 5 threading libraries. Take a look at this Javadoc for example and you'll find references to this technique:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

As long as your programm isn't sharing an application server with others, shuting down the VM by calling System.exit(0) terminates all threads.
From Javadoc
System.exit Terminates the currently running Java Virtual Machine)
EDIT:
If you want to do some clean up code before shutdown, http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html

There is on "one-size-fits-all" answer to this that's a drop-in replacement for System.exit, unfortunately.
You will generally need to set some kind of flag that signals to all of your threads that it is time to exit, and ensure that they check this flag regularly. This will let them clean up gracefully without stopping abruptly, and it also ensures the effects are limited to your own components. In this case your application's main thread would also observe the flag, wait for all the "worker" type threads to finish and would then return all the way up the stack until your application's entry point was reached.
This question is not too dissimilar to the deprecated Thread.stop (etc) methods, especially with regards to replacing System.exit with something more respectful. In that light, the why is Thread.stop() deprecated page may be useful reading.
Throwing an exception (a custom one called something like ApplicationStopException) to unwind the stack of the main thread is not such a bad idea; this prevents you from having to handle the special logic all over your code and instead lets the "message" propagate to the higher levels, where they can take whatever action is needed to exit your program gracefully.

I recommend you to do flagging to stop the thread so that the thread will know when it has to stop. For GUI and window, you can call frame.dispose().
For System.exit(), I think it will not affect the caller, you may try to see what is the real effect but as other people already recommended, do not call it directly like that, just let the threads stop by itself

Related

Reliably stopping an unresponsive thread

I'm wondering how to stop an unresponsive thread in Java, such that it's really dead.
First of all, I'm well aware of Thread.stop() being deprecated and why it should not be used; there are already many excellent answers on this topic, cf. [1][2]. So, the question more precisely is, whether it's actually technically possibly to kill a thread which code is not controlled by us but possibly hostile and not responding to interrupts.
In the simplest case, a hostile thread would be running while(true);, but it could as well be using up memory or other system resources to do more damage. Calling interrupt() on that thread is obviously ineffective. What about calling stop() instead?
I have run this in a debugger and, in fact, the thread really disappears. But is this approach reliable? The hostile thread could be prepared for this case; think of try{run();}catch(ThreadDeath t){run();} where it catches the ThreadDeath that is produced when we call stop() and recursively calls itself again.
As an outside observer, we cannot see what is going on; Thread.stop() always runs silently. Worst of all, the usual diagnostics won't work anymore (tried this while debugging on Corretto 1.8.0_275 Windows x64): Thread.getState() always returns RUNNABLE regardless of success in killing the thread, same goes for Thread.isAlive() (always true).
It may not be possible, at least not reliably in every scenario.
IF I understand the mechanism correctly (and there is some uncertainty there), if the code executes in such a way that there are no safepoints during the execution (for example in counted loops), it is not possible for the JVM to signal to the thread that it should stop (the thread never polls for an interrupt).
In such a scenario, you need to kill the JVM process, rather than the thread.
Some extra reading:
How to get Java stacks when JVM can't reach a safepoint
Counted loops
In a nutshell, there's no 100% reliable way to stop a Thread the way you'd like it.
Why?
This is an explanation for others who don't know why, anyone who knows the issue can skip this.
The way how threads are intended to be terminated forcefully is with the interruption state of the Thread. A Thread should be terminated with its interrupt() method is called which sets a boolean flag to true.
When the interruption flag is set to true, the Thread should terminate itself with virtually no delay.
Anyway the Thread can choose to simply ignore this and keep on running.
This is when the stop() method can be called that forces the Thread to terminate. The problem is that this method messes up concurrency, can damage objects and the program can be corrupted without a warning for the user. See Why the stop() method is deprecated?
At the end I could think of two possible ways, one is basically your way, the other one is safer but more complicated.
As an example, a hostile third party .jar which contains a Thread that refuses to terminate can cause these problems.
Quick & Dirty
This solution isn't completely safe but based on the usage this may be acceptable unless you really like security.
Try to first to call the interrupt() method on the Thread and give it a bit time to terminate.
If the Thread doesn't respond, you can either:
terminate the program and warn the user to not run that Thread again.
stop() the thread and hope for the best.
Complicated & Safe
The safest solution I can think of is creating a whole new process to run the Thread in. If the Thread doesn't want to terminate after interrupt(), you can just end the process with System.exit(-1) and let the OS handle it.
You need Inter Process Communication to communicate with the other process and that makes it a lot more complicated but also safer.
Related
How do you kill a Thread in Java?
What is an InterruptedException in Java? (Disclaimer: I've answered it)
What does java.lang.Thread.interrupt() do?
For me isAlive returns false if the process finishes due to Thread.stop.
I've made the following example, and it successfully kills the errant thread.
import java.util.Arrays;
public class BrokenThreads{
static boolean[] v = { true };
public static void call(){
try{
while(true){
Thread.sleep(200);
}
} catch ( Throwable td){
System.out.println("restarting");
call();
}
}
public static void main(String[] args) throws Exception{
Thread a = new Thread( BrokenThreads::call);
a.start();
Thread.sleep(500);
System.out.println( Arrays.toString( a.getStackTrace() ) );
while(v[0]){
a.stop();
System.out.println(a.getStackTrace().length);
v[0] = a.isAlive();
}
System.out.println("finished normally");
System.out.println( Arrays.toString( a.getStackTrace() ) );
}
}
Note that "getStackTrace" takes time, and you can see the stacktrace accumulate as recursive calls are made, until two stops happen quick enough to end the thread.
This uses two techniques to see if the thread has stopped. isAlive and the depth of the stack trace.
I think the question describes a scenario that is the reason why Thread.stop() is deprecated since ages now, but was not yet removed … just to have a 'last resort option', to be used only when being really desperate and being aware of all the negative impact.
But that call to Thread.stop() must be build into the code somehow, same as any alternative one may think about – so why not just fix the code for the thread? Or, if that is not possible because that code comes with a third party library without source code, why not replacing that library instead?
Ok, during testing, your own code may go wild, and you need an emergency break – for that, Thread.stop() is still good enough if you do not want to kill the whole JVM (what would be the better option in most of the cases). But again, you have to build this into the code before you start the test …
But in production, there should never be a thread that does not stop when receiving an interrupt. So there should be no need for a replacement of Thread.stop().
This can potentially open a can of worms like memory access violations which will kill the JVM itelf.
What you could do is isolate the thread, running .finalize() on it, then forcing the JVM to run GC operations such as Runtime.gc(), System.runFinalization() while forcing interruptions on that particular thread in order to bypass it's resurrection behavior.
I think .finalize() is effectively deprecated since java11 or maybe sooner, so it probably won't help you much.
If you really want to secure your runtime during it's operational cycles, your best bet would be to find a way to essentially map out your configuration before you start it, and have monitoring tools set up which cross-check against that map and monitor the integrity of your runtime while looking for injected classes and/or threads. ... this is assuming of course, you're attempting to guard against "virus-like" attacks in your jvm ... which is not exactly unheard of but still pretty rare.
If you're running some code off the internet, you could simply solve the issue with a call hierarchy inspection and figure out what spawns that problematic thread.
Note: If that invasive thread is calling native dll code which is looping back into it's caller, then your JVM will crash if you mark sections of it's address space as garbage collected.

How to kill all the threads in application That are designed by 3rd party library

I am facing an issue that when I run second instance of my application on the same port - I am getting SocketException: java.net.BindException: Address already in use: bind
The problem is that after getting this exception my application continue running.
After some hours I have noticed that (using "Get thread dump" tool) there are some threads still alive even after main is died.
I don't have access to that threads that means that I am not able to design it in way that I can interrupt them properly
Also, thread.interrupt, thread.setDaemon(true), thread.stop - nothing helped me.
How to stop that threads?
I am working on very big legacy application and threads that I want to stop are created in library that I don't access
You cannot forcibly stop threads in java. The thread has to work with you: It needs to have a core loop that looks a bit like this:
while (running && !Thread.interrupted()) {
// do something that won't take long.
try {
Thread.sleep(1000L); // or some other 'wait a while' code.
} catch (InterruptedException e) {
return;
}
}
If the code of the thread doesn't have this, and you can't change it, there's not a lot you can do about it. Thread.stop does not work on modern javas because that 'model' (throw a particular exception inside the thread, where-ever it is right now) is just something that makes for buggy software (because locks and such are unlikely to be properly closed and such): Therefore it has been deprecated for a decade now and no longer works at all. Even if it did, a thread can prevent you from stopping it.
Which leads us to the one surefire way to definitely, absolutely, kill a thread:
System.exit(0);
that'll do it. It is a common misconception that 'nice' code style is to never forcibly exit like that, with the right style being to tell all (non-daemon-status) alive threads to clean up their business and exit.
This is mistaken. Just exit. Your code should be written not to need to do any cleanup of resources, because if you write it like that, it means if someone trips over a powercable or java is hard-killed, your app just created a mess. The few cleanup jobs you do have should be registered as shutdown hooks.
So, if you want to quit the VM, just System.exit.
Of course the very first thing to do is to try and fix the other side of the code. If you can't do that and at the same time you can get a hold of those threads - you could call interrupt on them; and again, hope that the person that wrote that code knew how to handle those interrupts.
Otherwise, you are completely out of luck, unless System::exit is an option and a restart I guess. But again, this is not really your problem that some other resources, out of your control, do not clean up after themselves.
Even if they do respond to interrupts, what if you leave your database/file manager/whatever in a corrupt state?

Set Java exit code without exiting yet

In a highly concurrent program with lots of shutdown operations, wondering how to set the exit code without prematurely calling System.exit()? Possible to set an "execute this code when everything else is done" method? but I'd really just like to prematurely set the exit code.
If I understand correctly what you want is to somehow keep the exit code, run some methods and then call System.exit with the pre-decided exit code.
IMO what you should do is use Shutdown hooks instead. I.e. your code will run before the JVM shuts down and (if I got your requirement correctly) will have the same result with a straightforward coding implementation (i.e. instead of using using state variable and unusual coding logic to achieve what you are trying to do etc)
Have a master thread spawn off all other threads such that it only shuts down when all other threads are complete.
In a highly concurrent program with lots of shutdown operations
This is a code smell to me.
I can understand how multiple threads might want to shut down, but they shouldn't be allowed to do so.
Instead, I would create a global method called initiateShutdown(int code). This method would contain logic to determine when it's appropriate to actually shut down. Since you may not want a thread returning from this method, you could implement some sort of never-returning lock, and consign the thread to waiting on this lock.
Just store the result somewhere and use any suitable synchronization tool to tell that you are done. When you are done, just read the stored result and exit using System.exit(result).
I'm curious, if several threads set the result, which should you use?

How to kill non-interruptable thread?

We run an AI programming competition in which contestants will code an AI that runs on the JVM using our API we provide them. We put them into a sandbox by limiting what they can do with a SecurityManager, and during runtime they simply set several flags which are their decisions. The only interaction between our system and their AI is through these flags, so there are no bad effects on us if their thread were to suddenly die.
When an AI computes far too long, we would like to shut down their thread. However, we can't find a way of guaranteeing that we will destroy their thread. One possible reason for this is that the AI goes into an infinite loop with no blocking, making Thread.interrupt() useless. Thread.stop() is unreliable since if they are in a try catch block the ThreadDeath exception will be caught, and has no issues for us because they don't touch anything bad and we don't care if they die.
Currently we just ignore their thread and continue on without them after they time out, but their infinite loop will continue processing in the background until the JVM dies. This is unacceptable to us because we will be running matches in the background on a web server 24/7, so we want as much stability as possible. One thought has been to run each game in a separate JVM, but that is far more complex than we would like to get.
Is there any sure fire way to destroy the thread?
Provide them with a method they MUST call on a regular basis, even during their computation. If you judge they are 'dead' make the method sleep forever. Obviously his will not work if they are truly dead but you should catch most issues.
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop%28java.lang.Throwable%29
Pass in a custom subclass of Throwable that they can't know about, and you can check their code with the regex: /catch\s*(\s*Throwable/ to ensure that they don't catch Throwable anywhere.
In general, no, you should not stop an arbitrary thread in a JVM (thus the methods are deprecated). The root of the problem is that you have no idea where in the system the thread is when you kill it. In the worst case it could be in the middle of a synchronized block inside the the JVM's infrastructure that is unprepared for an unexpected exception to be thrown. (Its nearly impossible to write robust synchronized code that can be killed by an exception at arbitrary points.)
See the highly-rated answer on this question for more details:
Are java app servers able to destroy threads? If yes, how?
You might be able to get away with a cooperative design where you ask the AI thread to exit. If it does, then you're good. If it does not, then you need to restart the JVM.
After trying several things, we came to the conclusion that there is no guaranteed solution. By calling stop() on a thread, that thread is capable of catching the ThreadDeath throwable and ignoring it entirely. Thus, if it's in a while loop continuously catching it, or if it calls a method recursively that catches it, it is not guaranteed that you can kill it.
Since we didn't have any control over the code that would be running in that case, and that code was not necessarily in Java (we were also supporting Jython), the best solution we could come up with was spawning a thread that went into a loop that continuously called suspend() and then stop() on the thread. The result worked for most cases, but occasionally was unable to kill a malicious thread.

Kill an object in java

I am currently using JMX to manage and monitor a huge migration process which is executed within a Java class.
I would like to be able to abort and kill the process when I needed, e.g. customer/time required, or some dead loop happens within a single migration.
Here, we call abort a gracefully way to kill a thread by setting up a boolean flag and once every loop will check the flag first and then decides whether to proceed or not. This has been implemented without any issue.
However, I am having troubles with kill the thread. My colleague had suggested me to override the finalize() method and try to kill it within it. However, what I have found online is this method will not be able to destroy the object and it is recommned to be called by GC but the user instead.
I guess the theory is OK that as long as the object is destroyed, no more process will be able to happen. I am just not sure whether this is able to be implemented in JAVA or not.
Also, I would like to know, is there any other ways that you guys can give me a hint.
Would be very appreciate your help.
P.S: by relating to JMX, doesn't mean it really has to do with JMX, it just I would like this killing command is coming from the JMX console client.
It's a bit hard to understand what you are saying, but I don't think that finalize is going to be any help.
A live thread (i.e. one that has been started and has not yet terminated) is reachable by definition, and therefore won't be garbage collected. So adding a finalize method to it won't have any affect.
If the object you are talking about is not the thread, adding a finalize probably won't help either:
If the thread's runnable (or whatever) has a reference to the object, that will stop it from being garbage collected.
If it doesn't, and the object does become unreachable, the finalize method won't run until after the GC has decided to collect the object ... and that may never happen.
Even if the finalize method did get called, what could it do? You've already told the thread to shut down ... and nothing has happened.
The real problem here seems to be that the thread is not responding to your "graceful shutdown" flag.
I'd try to fix this by using Thread.interrupt() and Thread.isInterrupted() rather than a custom flag. This has the advantage that an interrupt will also unblock things like Thread.sleep Object.wait and certain I/O operations.
If the thread is blocked trying to talk to some external service via a socket or pipe, you could unblock it by closing the socket and/or stream. This of course assumes that your shutdown code can get its hands on the reference to the Socket or Stream object.
If those approaches failed, I'd consider pulling the plug on the entire application by calling System.exit() ... if that's a reasonable thing to do.
If you are totally desperate (and a little bit insane) you could consider using the deprecated Thread.abort() method. But there is a distinct possibility that that would leave your entire application in a broken and unresponsive state. So I would NOT recommend this approach.
The other possibilities to consider are:
that the Thread has actually responded and exited, but your shutdown code didn't notice,
that the Thread died before you tried to shut it down it, and your shutdown code didn't notice,
that the Thread is deadlocked, or
that there is some long running (but not infinite) loop in the runnable needs to be modified to check the "you die now" flag more often.
Some of these things you could be diagnosed by attaching a debugger and taking a thread dump.
I think you said that you saw advice to the effect that it was a BAD IDEA to call System.gc(). This is good advice.
You should perform certain task in finally which you want to perform when method exits in any condition. Most preferable example people give about this is cosing database connection.
Yes it is recommended to leave Garbage Collection on JVM.
JVM takes care of destrying objects.

Categories