How to check if one of the thread has failed? - java

I have a multi-threaded Java application. I want the whole application to fail is one of the thread encounters any exception.
I don't think doing System.exit(); inside the thread will exit the whole app.
Can someone suggest a way?

put try-catch in Thread's run method and in catch block System.exit(0); it works.

actually, calling System.exit() will exit the whole app, but that's generally not what you want in your library code (for instance, it makes unit testing difficult).
a better implementation is to have a shared "error handler" reference, with an implementation that you control. in unit tests, you could just log the exception. in your real app, you could call System.exit().

One simple way to do that is to have try{} catch{} on each thread, when you catch exception you may call static function that exits the application.

Related

How to stop a java program if it is determined it should not run?

If I want to check if some preconditions are present in order to run a java program what is best?
Do:
System.exit(1);
Or throw a RuntimeException in main to end the main thread? (No other threads running yet)
Ideally you terminate your threads gracefully. System.exit(1) works too, but it is better if your threads get signalled that they need to stop what they're doing and terminate by finishing what they're doing (i.e. executing their method till the end). It depends on your design obviously.
Throwing a RuntimeException seems too ungraceful and could lead you to behaviour you don't actually want.
You're better off calling exit as exceptions are used to help you catch errors in programming flow and deal with them accordingly.
From a user's perspective having the application print to System.err the issues and then closing gracefully is much more intuitive than seeing a stack trace or other code notations like EXCEPTION that they shouldn't be expected to understand.
If you want a stack trace, go with the RuntimeException, if not System.exit(1) is cleaner.
Either is good, but I would prefer to use the System.exit() as the RuntimeException could be considered misleading.
Not having more information than what you posted I would do something like this:
public static void main(String[] args) {
boolean precondition = ... // determine your precondition here
if (precondition) {
// run program
} else {
System.out.println("Preconditions not satisfied.");
}
}
Never force the exit. Program your runtime method in a way allowing your application to run out of methods and close by itself. I suggest drawing a graph before any structural application.

Java breaking an infinite loop

I have particular situation in our production environment, where a particular piece of code goes into an infinite loop. The cause is mostly data specific and not able to figure out the true cause. In the mean time, what I am hoping to do is spawn a separate child thread to execute that piece of code, and if it executes for say more than 30s, want to stop that child thread from executing
Thread t = new Thread() {
public void run() {
// This is where i will the method that runs in a infinite loop
callMethodThatRunsInInfiniteLoop();
};
};
t.start();
try {
t.join(2000); // wait 2s
} catch (InterruptedException e) {
e.printStackTrace();
}
// if not completed how to break the child thread ???
unfortunately no it is a thirdparty code, and will not be able to change it so easily.
It sounds like you are trying to work around a problem in the third-party library ... or in your code calling the third-party library with bad input or something.
My advice would be to fix THAT problem, rather than trying to kill the errant thread(s). And if you can't do that, then you have two choices:
modify the 3rd party library to be interrupt aware/responsive, and then use that to stop it, or
try to find a way to "reach into" the 3rd party library's data structures (e.g. using nasty reflection) and cause it to die.
If you are resorting to the latter, then maybe you should also look at running the 3rd party library in a separate JVM so that you can forcibly kill it using the Process API.
Having said that, there are limited circumstances where Thread.stop() is actually (probably) safe to use. Basically, if the errant thread doesn't create child threads, doesn't interact with other threads and doesn't share data structures, and can't be doing class initialization when you kill it, then you are probably going to be safe. The problem is there are so many theoretical scenarios where stopping the thread could cause damage that it is hard to know that you've considered all of them.
Is there a way to cause the infinite loop code to break by throwing an exception? e.g. set some variable to
null? A possible advantage is that the affected thread (if well written) will clean up after itself and shut down more nicely than a stop().
All methods for stopping a thread 'purely externally' are deprecated and considered unsafe. The only way a thread can be safely stopped requires
modifying the code which is running to check whether it has been politely asked to stop via some stopMe variable being set; or
co-opting a variable the other thread already uses to cause the thread to quit (which is generally very bad practice); for example, by forcing it to throw an exception, as suggested by user949300.
Without this, you have no choice but to use an unsafe method, which means Thread.stop(), which is also very bad practice. This is a very bad idea, and of course the only real solution is to either change your input so that this doesn't happen, or get the third-party code fixed.
Any objects the thread was using may be in an inconsistent (and possibly unusable) state, so try to avoid letting the Thread modify anything important, and don't look at any of its output variables if you can help it.
The Thread.stop() method still seems to exist in Java SE 7, though is of course deprecated, but I can't vouch for your particular environment.
See http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Depending on the implementation of the method, you could start it in its own JVM, then stop it by calling destroy() on the process:
Process process = new ProcessBuilder("java", "-cp", "/some/class/path", "com.mycompany.MyLauncher").start();
// sometime later
process.destroy();

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.

Stopping a thread that could be looping forever

I have a program where I compile java code a user types into a text field, and then run it. A run the code in a seperate thread, so that the GUI they use to input the source code doesn't get locked up.
The GUI has an abort button that should stop the thread. My issue is that I need to stop the compiling thread no matter what is going on inside of it, which means I must account for a case where the thread is caught in an infinite loop (due to user error), and it cannot properly end itself using a safe flag. I've read up on many solutions that involve using a flag of some kind, but they aren't available to me because of this looping issue. I need to have the thread stop and the memory it's using freed (I can't just let it sit in the background forever, unless that is the only solution left). Any advice or alternative solutions? Hopefully some fresh perspectives could help squash this issue.
Edit:
Here's a sample bit of user submitted code:
public class RunMe extends SomethingThatRuns {
public void run() {
int i = 0;
while (i = 0) {
//Prepare to get stuck!
}
}
}
I'll compile this class, and then run it. This is where it will get stuck, and the run() method can never finish, or even loop to check a flag.
You can run it in a new JVM so you can kill it when you want.
Thinking about security this may be a good thing to do too.
Call stop() on the thread.
Yes, this is a deprecated method. However, it really shouldn't be "deprecated", it should be "dangerous." In some circumstances, however, there's really no choice but to use it, and the invocation of an "agent" provided by a user is one of those cases.
Make sure that your program doesn't use any data that are manipulated by this user thread; or, if you do, devise some transactional mechanism to exchange data safely between the threads.
Even this method isn't guaranteed to terminate the thread. For example, the user can catch the resulting Throwable and ignore it. Or, the thread implementation might not respond to stop() calls if the thread is in some native code. But it's your best chance.
The core issue here is the fact that the code even allows an infinite loop to be entered as part of user error. Fix that, and everything else will become easier to deal with.
Properly-behaving threads should usually terminate themselves gracefully when there's no work to do (or return quietly to a thread pool to ask for more work, if that's your application's design). If you feel like you need to have one thread forcefully kill another then you've likely got a fundamental design issue. It's fine to have one thread tell another, "Hey, you should terminate now so that I can join with you..." because that allows your threads to clean things up as they finish. Forcefully destroying threads just isn't the right way to manage these situations.
You can use them to insert a interrputed check in every loop and maybe in other places too.
I can see two options:
As you compile the user code you can edit it before. You may use
ANTLR to parse and modify the code.
There are bytecode manipulation frameworks like ASM that allow you to manipulate code that is already
compiled.
I don't think it is easy but it might be a way.
interupt(); the Thread in the gui
and in the code that the thread runs regularly check for Thread.interrupted() and throw an exception when you do especially inside loops
At a high level, you are asking how one thread might go about stopping another thread. To that end, see this SO question Stopping a Thread in Java?.

How can I close my software in a safe way?

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

Categories