Code:
outerMethod {
#Override
public void run() {
innerMethod throws IOException
}
}
Method that exceuted in thread throws checked exception - IOException.
I need to handle this exception in main thread.
Like:
outerMethod() throws IOException
{
#Override
public void run() {
innerMethod() throws IOException
}
}
Is this possible? If no, what would be a better way to do this?
Thanks.
Use FutureTask http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html#get%28%29 . It's get methods will encapsulate any exceptions from the task that might have run on another thread.
ExecutionException: Exception thrown when attempting to retrieve the result of a task that aborted by throwing an exception. This exception can be inspected using the Throwable.getCause() method.
Thread is an individual process and you cannot propagate your exception to other thread as they cannot talk through the exception route. However you can use inter thread communication and you will have to logically handle the case when an exception occurs.
From this API doc
If thread has defined UncaughtExceptionHandler, it will be invoked,
Else thread group's UncaughtExceptionHandler will be invoked if defined,
Else it can forward to default uncaught exception handler.
You have to handle exceptions inside run method :
#Override
public void run() {
try {
innerMethod();
} catch (Exception e) {
//handle e
}
Related
Here is my parser class:
public class InputFilesParser {
private ExecutorService executorService;
private volatile Throwable thrownError;
public InputFilesParser(int poolSize) {
this.executorService = Executors.newFixedThreadPool(poolSize, (r) -> {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler((thread, e) -> {
//this should be called before the thread has finished.
this.notifyOnException(thread, e);
});
return t;
});
}
}
public void parseFile(Path inputFilePath) throws Throwable {
//if exception is set, then no more files will be processed.
if (this.thrownError != null) {
//execution will stop here because an error will be thrown from waitToFinish()
this.waitToFinish();
}
this.executorService.execute(() -> {
//this will always throw an exception which have to be handled by the above mentioned uncaughtExceptionHandler.
this.processFile(inputFilePath);
});
}
private void processFile(Path inputFilePath) {
throw new RuntimeExecption();
}
public void waitToFinish() throws Throwable {
this.executorService.shutdown();
while (true) {
try {
//if statement will be entered only when awaitTermination returns true, meaning all the tasks are finished.
if (this.executorService.awaitTermination(STOP_CHECK_TIMEOUT, TimeUnit.SECONDS)) {
synchronized (this) {
//in this scenario, after all tasks are finished, the thrownError should be set
if (this.thrownError != null) {
//I expect to get this output
System.out.println("Exception: " + this.thrownError);
throw this.thrownError;
}
//but I get this output
System.out.println("No exception: " + this.thrownError);
}
break;
}
} catch (InterruptedException e) {
LOG.info("An interruption occurred", e);
}
}
}
private synchronized void notifyOnException(Thread thread, Throwable t) {
//if the thrownError isn't set, then set it here so that waitToFinish() will know that an error occurred.
if (this.thrownError == null) {
this.thrownError = t;
}
}
}
on the calling thread, I have the following:
InputFilesParser ifp = new InputFilesParser(poolSize);
try {
for (Path f : files) {
//each parsing will throw an exception in this scenario
ifp.parseFile(f);
}
//an exception should be detected and the error thrown, but actually this is not happening, but printing No exception... message.
ifp.waitToFinish();
catch(Exception e) {
e.printStackTrace();
}
Although there is an exception thrown, the calling thread gets in waitToFinish() method, printing null for the thrown exception:
Thread: Thread-5. No exception: null
This means that awaitTermination returns true, before the exception is set in notifyOnException method. But notifyOnException method is called from a thread run by this executor service. In my opinion there is a problem with my understanding, or there is a problem with java.
Any idea which one of this :) ? In my opinion, this shouldn't be possible. Am I missing something about setUncaughtExceptionHandler method and the way how it handles the exceptions? Although from documentation it seems that this method is called by the thread throwing the exception.
public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
Set the handler invoked when this thread abruptly terminates due to an uncaught exception.
A thread can take full control of how it responds to uncaught exceptions by having its uncaught exception handler explicitly set. If no such handler is set then the thread's ThreadGroup object acts as its handler.
Parameters:
eh - the object to use as this thread's uncaught exception handler. If null then this thread has no explicit handler.
Thanks in advance.
It seems to me that my assumption in regard to UncaughtExceptionHanlder's method call is wrong.
Java docs says this:
public static interface Thread.UncaughtExceptionHandler
Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception.
When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler's uncaughtException method, passing the thread and the exception as arguments.
With other words, it is not the thread itself which calls the UncaughtExceptionHandler's method, but JVM. This means that there is no constraint in regard to the order of operations when awaitTermination is called.
Exception handling is not designed to process problems associated with asynchronous events (e.g., disk I/O completions, network message arrivals, mouse clicks and keystrokes), which occur in parallel with, and independent of, the program’s flow of control.
How is exception handling not designed to handle asynchronous events? Why is this the case?
I'll be thankful if you enhanced your answers by quite detailed examples.
I think that is a misleading statement.
Asynchronous work is done through threads in Java (or processes but that is a different matter).
What is true is that if you start a thread and an exception is thrown in that thread, you won't be able to catch it from your main thread.
But nothing prevents you from handling exceptions in that new thread.
Example - the code below prints Exception was raised in the thread but we can still handle it:
public static void main(String[] args) throws Exception {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
throw new RuntimeException("oops");
}
});
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Exception was raised in the thread but we can still handle it");
}
});
t.start();
}
Alternatively, you can add some exception catching logic within the Runnable itself.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the best approach to handling exceptions thrown in a separate thread?
When bad things happen, my code throws an Exception, that is later being caught and handled.
If said code runs as part of a thread however, public void run() does not throw Exception. How can the executor of the tread know about exception being thrown?
Now:
A a = new A();
try {
a.doSomething();
} catch (Exception e) {
// do something clever
}
With Threads
Thread t = new Thread (new A());
t.start(); // run() calls doSomething()
If this threads fails with exception, how can i know about it?
You can set an uncaught exception handler on the thread via Thread.setUncaughtExceptionHandler(), which will handle any exceptions that are not handled within your code.
Essentially:
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e)() {
// do whatever
}
});
Also, if you want a handler for all threads, you can call Thread.setDefaultUncaughtExceptionHandler which is a static method to provide a handler for threads when there isn't one specifically for it.
you can catch the exception in-thread and then pass it as an event to the creator thread.
You can use an ExecutorService
ExecutorService es =
Future<Type> future = ex.submit(new Callable<Type>() {
public Type call() throws Exception {
// do something
return result;
}
});
// later
try {
Type result = future.get();
} catch(ExecutionException e) {
Throwable exceptionThrown = e.getCause();
}
if you don't have anything to return you can use the following.
Future<Void> future = ex.submit(new Callable<Void>() {
public Void call() throws SpecificException {
// do something which might throw SpecificException
return null;
}
});
I am creating some multi-threaded code, and I have created a JobDispatcher class that creates threads. I want this object to handle any unhandled exceptions in the worker threads, and so I am using
Thread.setUncaughtExceptionHandler(this);
Now, I would like to test this functionality - how can I generate an unhandled exception in the run() method of my worker object?
Just throw any exception.
E.g.:
throw new RuntimeException("Testing unhandled exception processing.");
Complete:
public class RuntimeTest
{
public static void main(String[] a)
{
Thread t = new Thread()
{
public void run()
{
throw new RuntimeException("Testing unhandled exception processing.");
}
};
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
System.err.println(t + "; " + e);
}
});
t.start();
}
}
What's the problem with just throwing an exception:
throw new Exception("This should be unhandled");
Inside your run method. And of course, not catching it. It should trigger your handler.
You should throw some unchecked exception. An unchecked exception does not require your code to handle it, and is therefore a good candidate to make all the way down the call stack.
You can choose RuntimeException for example, or even something like AssertionError, if you want to minimize the chances that some part of the code catches the exception and handles it before it reaches your handler.
just add this code and you'll get unhandled exception without lint error:
int i = 1/0;
If I invoke the run() method on a Thread and the run() method throws an uncaught Exception what would be the outcome ?
Who catches this Exception? Does the Exception even get caught?
If there is an exception handler installed for the ThreadGroup, the JVM passes the exception to it. If it's an AWT thread, you can install an event handler for otherwise unhandled exceptions. Otherwise the JVM handles it.
Example of a thread group with a custom handler and how to use it:
public class MyThreadGroup extends ThreadGroup {
public MyThreadGroup() {
super("My Thread Group");
}
public void uncaughtException(Thread t, Throwable ex) {
// Handle exception
}
}
Thread t = new Thread(new MyThreadGroup(), "My Thread") { ... };
t.start();
Example of using an AWT exception handler:
public class MyExceptionHandler {
public void handle(Throwable ex) {
// Handle exception
}
public void handle(Thread t, Throwable ex) {
// Handle exception
}
}
System.setProperty("sun.awt.exception.handler", MyExceptionHandler.class.getName());
If you've submitted the Runnable to an ExecutorService you can catch the Exception as wrapped inside a ExecutionException. (Highly recommended over simply calling run())
It can if you assign it to a ThreadGroup that implements the uncaughtException(Thread, Throwable) method.