How to catch an Exception from a thread - java

I have Java main class, in the class, I start a new thread, in the main, it waits until the thread dies. At some moment, I throw a runtime exception from the thread, but I can't catch the exception thrown from the thread in the main class.
Here is the code:
public class Test extends Thread
{
public static void main(String[] args) throws InterruptedException
{
Test t = new Test();
try
{
t.start();
t.join();
}
catch(RuntimeException e)
{
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run()
{
try
{
while(true)
{
System.out.println("** Started");
sleep(2000);
throw new RuntimeException("exception from thread");
}
}
catch (RuntimeException e)
{
System.out.println("** RuntimeException from thread");
throw e;
}
catch (InterruptedException e)
{
}
}
}
Anybody knows why?

Use a Thread.UncaughtExceptionHandler.
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread() {
#Override
public void run() {
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException();
}
};
t.setUncaughtExceptionHandler(h);
t.start();

That's because exceptions are local to a thread, and your main thread doesn't actually see the run method. I suggest you read more about how threading works, but to quickly summarize: your call to start starts up a different thread, totally unrelated to your main thread. The call to join simply waits for it to be done. An exception that is thrown in a thread and never caught terminates it, which is why join returns on your main thread, but the exception itself is lost.
If you want to be aware of these uncaught exceptions you can try this:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Caught " + e);
}
});
More information about uncaught exception handling can be found here.

This explains the state transition of threads dependening on whether an exceptions occured or not:
Source : http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf

Most likely;
you don't need to pass the exception from one thread to another.
if you want to handle an exception, just do it in the thread which threw it.
your main thread doesn't need to wait from the background thread in this example, which actually means you don't need a background thread at all.
However, lets assume you do need to handle an exception from a child thread another. I would use an ExecutorService like this:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
System.out.println("** Started");
Thread.sleep(2000);
throw new IllegalStateException("exception from thread");
}
});
try {
future.get(); // raises ExecutionException for any uncaught exception in child
} catch (ExecutionException e) {
System.out.println("** RuntimeException from thread ");
e.getCause().printStackTrace(System.out);
}
executor.shutdown();
System.out.println("** Main stopped");
prints
** Started
** RuntimeException from thread
java.lang.IllegalStateException: exception from thread
at Main$1.call(Main.java:11)
at Main$1.call(Main.java:6)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
** Main stopped

Please take a look at Thread.UncaughtExceptionHandler
Better (alternative) way is to use Callable and Future to get the same result...

Use Callable instead of Thread, then you can call Future#get() which throws any exception that the Callable threw.

AtomicReference is also a solution to pass the error to the main thread .Is same approach like the one of Dan Cruz .
AtomicReference<Throwable> errorReference = new AtomicReference<>();
Thread thread = new Thread() {
public void run() {
throw new RuntimeException("TEST EXCEPTION");
}
};
thread.setUncaughtExceptionHandler((th, ex) -> {
errorReference.set(ex);
});
thread.start();
thread.join();
Throwable newThreadError= errorReference.get();
if (newThreadError!= null) {
throw newThreadError;
}
The only change is that instead of creating a volatile variable you can use AtomicReference which did same thing behind the scenes.

Currently you are catching only RuntimeException, a sub class of Exception. But your application may throw other sub-classes of Exception. Catch generic Exception in addition to RuntimeException
Since many of things have been changed on Threading front, use advanced java API.
Prefer advance java.util.concurrent API for multi-threading like ExecutorService or ThreadPoolExecutor.
You can customize your ThreadPoolExecutor to handle exceptions.
Example from oracle documentation page:
Override
protected void afterExecute(Runnable r,
Throwable t)
Method invoked upon completion of execution of the given Runnable. This method is invoked by the thread that executed the task. If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.
Example code:
class ExtendedExecutor extends ThreadPoolExecutor {
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
Usage:
ExtendedExecutor service = new ExtendedExecutor();
I have added one constructor on top of above code as:
public ExtendedExecutor() {
super(1,5,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
}
You can change this constructor to suit your requirement on number of threads.
ExtendedExecutor service = new ExtendedExecutor();
service.submit(<your Callable or Runnable implementation>);

Also from Java 8 you can write Dan Cruz answer as:
Thread t = new Thread(()->{
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException(); });
t.setUncaughtExceptionHandler((th, ex)-> log(String.format("Exception in thread %d id: %s", th.getId(), ex)));
t.start();

I faced the same issue ... little work around (only for implementation not anonymous objects ) ... we can declare the class level exception object as null ... then initialize it inside the catch block for run method ... if there was error in run method,this variable wont be null .. we can then have null check for this particular variable and if its not null then there was exception inside the thread execution.
class TestClass implements Runnable{
private Exception ex;
#Override
public void run() {
try{
//business code
}catch(Exception e){
ex=e;
}
}
public void checkForException() throws Exception {
if (ex!= null) {
throw ex;
}
}
}
call checkForException() after join()

Did you play around with setDefaultUncaughtExceptionHandler() and the alike methods of the Thread class? From the API: "By setting the default uncaught exception handler, an application can change the way in which uncaught exceptions are handled (such as logging to a specific device, or file) for those threads that would already accept whatever "default" behavior the system provided."
You might find the answer to your problem there... good luck! :-)

If you implement Thread.UncaughtExceptionHandler in class that starts the Threads, you can set and then rethrow the exception:
public final class ThreadStarter implements Thread.UncaughtExceptionHandler{
private volatile Throwable initException;
public void doSomeInit(){
Thread t = new Thread(){
#Override
public void run() {
throw new RuntimeException("UNCAUGHT");
}
};
t.setUncaughtExceptionHandler(this);
t.start();
t.join();
if (initException != null){
throw new RuntimeException(initException);
}
}
#Override
public void uncaughtException(Thread t, Throwable e) {
initException = e;
}
}
Which causes the following output:
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter.doSomeInit(ThreadStarter.java:24)
at com.gs.gss.ccsp.enrichments.ThreadStarter.main(ThreadStarter.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter$1.run(ThreadStarter.java:15)

Exception handling in Thread : By default run() method doesn’t throw any exception, so all checked exceptions inside the run method has to be caught and handled there only and for runtime exceptions we can use UncaughtExceptionHandler. UncaughtExceptionHandler is an interface provided by Java to handle exceptions in a Thread run method. So we can implement this interface and set back our implementing class back to Thread object using setUncaughtExceptionHandler() method. But this handler has to be set before we call start() on the tread.
if we don’t set uncaughtExceptionHandler then the Threads ThreadGroup acts as a handler.
public class FirstThread extends Thread {
int count = 0;
#Override
public void run() {
while (true) {
System.out.println("FirstThread doing something urgent, count : "
+ (count++));
throw new RuntimeException();
}
}
public static void main(String[] args) {
FirstThread t1 = new FirstThread();
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Exception thrown by %s with id : %d",
t.getName(), t.getId());
System.out.println("\n"+e.getClass());
}
});
t1.start();
}
}
Nice explanation given at http://coder2design.com/thread-creation/#exceptions

It is almost always wrong to extend Thread. I cannot state this strongly enough.
Multithreading Rule #1: Extending Thread is wrong.*
If you implement Runnable instead you will see your expected behaviour.
public class Test implements Runnable {
public static void main(String[] args) {
Test t = new Test();
try {
new Thread(t).start();
} catch (RuntimeException e) {
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run() {
try {
while (true) {
System.out.println("** Started");
Thread.sleep(2000);
throw new RuntimeException("exception from thread");
}
} catch (RuntimeException e) {
System.out.println("** RuntimeException from thread");
throw e;
} catch (InterruptedException e) {
}
}
}
produces;
Main stoped
** Started
** RuntimeException from threadException in thread "Thread-0" java.lang.RuntimeException: exception from thread
at Test.run(Test.java:23)
at java.lang.Thread.run(Thread.java:619)
* unless you want to change the way your application uses threads, which in 99.9% of cases you don't. If you think you are in the 0.1% of cases, please see rule #1.

My solution with RxJava:
#Test(expectedExceptions = TestException.class)
public void testGetNonexistentEntry() throws Exception
{
// using this to work around the limitation where the errors in onError (in subscribe method)
// cannot be thrown out to the main thread
AtomicReference<Exception> ex = new AtomicReference<>();
URI id = getRandomUri();
canonicalMedia.setId(id);
client.get(id.toString())
.subscribe(
m ->
fail("Should not be successful"),
e ->
ex.set(new TestException()));
for(int i = 0; i < 5; ++i)
{
if(ex.get() != null)
throw ex.get();
else
Thread.sleep(1000);
}
Assert.fail("Cannot find the exception to throw.");
}

For those who needs to stop all Threads running and re-run all of them when any one of them is stopped on an Exception:
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// could be any function
getStockHistory();
}
public void getStockHistory() {
// fill a list of symbol to be scrapped
List<String> symbolListNYSE = stockEntityRepository
.findByExchangeShortNameOnlySymbol(ContextRefreshExecutor.NYSE);
storeSymbolList(symbolListNYSE, ContextRefreshExecutor.NYSE);
}
private void storeSymbolList(List<String> symbolList, String exchange) {
int total = symbolList.size();
// I create a list of Thread
List<Thread> listThread = new ArrayList<Thread>();
// For each 1000 element of my scrapping ticker list I create a new Thread
for (int i = 0; i <= total; i += 1000) {
int l = i;
Thread t1 = new Thread() {
public void run() {
// just a service that store in DB my ticker list
storingService.getAndStoreStockPrice(symbolList, l, 1000,
MULTIPLE_STOCK_FILL, exchange);
}
};
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable exception) {
// stop thread if still running
thread.interrupt();
// go over every thread running and stop every one of them
listThread.stream().forEach(tread -> tread.interrupt());
// relaunch all the Thread via the main function
getStockHistory();
}
};
t1.start();
t1.setUncaughtExceptionHandler(h);
listThread.add(t1);
}
}
To sum up :
You have a main function that create multiple thread, each of them has UncaughtExceptionHandler which is trigger by any Exception inside of a thread. You add every Thread to a List. If a UncaughtExceptionHandler is trigger it will loop through the List, stop every Thread and relaunch the main function recreation all the Thread.

You cannot do this, since it doesn't really make sense. If you hadn't called t.join() then you main thread could be anywhere in the code when the t thread throws an exception.

Related

Exception in child thread

I am creating a new Thread from the main thread using the below:
public static void main(String[] args) {
try {
new TestThread().start();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Inside main");
}
And throwing an exception. I am able to catch it in the main thread also.But according to article
this shouldn't be the case right?
EDIT:
public class TestThread extends Thread {
#Override
public void run() {
throw new RuntimeException();
}
}
Exception Trace
Inside main
Exception in thread "Thread-0" java.lang.RuntimeException
at TestThread.run(TestThread.java:8)
Exceptions thrown by a thread's run() method, are not caught by the main thread but handled by the JVM.
If you want to manage this situation, you should use the Thread.setUncaughtExceptionHandler method.
Something like this:
class MyHandler implements Thread.UncaughtExceptionHandler
{
#Override
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("Caught exception " + e.getMessage());
e.printStackTrace();
}
}
class MyThread extends Thread
{
public MyThread()
{
setUncaughtExceptionHandler(new MyHandler());
}
#Override
public void run()
{
throw new RuntimeException("ciao");
}
}
The article you refer to is "Java Thread: Run method cannot throw checked exception".
In Java, Thread's run method cannot throw checked exceptions because it would involve changing the signature of the run() method. However, in your example, you throw a RuntimeException, which isn't a checked exception. See Understanding checked vs unchecked exceptions in Java.
Note, however, that you are not actually catching the exception in the main thread: replace the printStackStrace statement with something like ...println("caught") for this to be more obvious.

no null pointer exception message in console inside the thread [duplicate]

I have Java main class, in the class, I start a new thread, in the main, it waits until the thread dies. At some moment, I throw a runtime exception from the thread, but I can't catch the exception thrown from the thread in the main class.
Here is the code:
public class Test extends Thread
{
public static void main(String[] args) throws InterruptedException
{
Test t = new Test();
try
{
t.start();
t.join();
}
catch(RuntimeException e)
{
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run()
{
try
{
while(true)
{
System.out.println("** Started");
sleep(2000);
throw new RuntimeException("exception from thread");
}
}
catch (RuntimeException e)
{
System.out.println("** RuntimeException from thread");
throw e;
}
catch (InterruptedException e)
{
}
}
}
Anybody knows why?
Use a Thread.UncaughtExceptionHandler.
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread() {
#Override
public void run() {
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException();
}
};
t.setUncaughtExceptionHandler(h);
t.start();
That's because exceptions are local to a thread, and your main thread doesn't actually see the run method. I suggest you read more about how threading works, but to quickly summarize: your call to start starts up a different thread, totally unrelated to your main thread. The call to join simply waits for it to be done. An exception that is thrown in a thread and never caught terminates it, which is why join returns on your main thread, but the exception itself is lost.
If you want to be aware of these uncaught exceptions you can try this:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Caught " + e);
}
});
More information about uncaught exception handling can be found here.
This explains the state transition of threads dependening on whether an exceptions occured or not:
Source : http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf
Most likely;
you don't need to pass the exception from one thread to another.
if you want to handle an exception, just do it in the thread which threw it.
your main thread doesn't need to wait from the background thread in this example, which actually means you don't need a background thread at all.
However, lets assume you do need to handle an exception from a child thread another. I would use an ExecutorService like this:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
System.out.println("** Started");
Thread.sleep(2000);
throw new IllegalStateException("exception from thread");
}
});
try {
future.get(); // raises ExecutionException for any uncaught exception in child
} catch (ExecutionException e) {
System.out.println("** RuntimeException from thread ");
e.getCause().printStackTrace(System.out);
}
executor.shutdown();
System.out.println("** Main stopped");
prints
** Started
** RuntimeException from thread
java.lang.IllegalStateException: exception from thread
at Main$1.call(Main.java:11)
at Main$1.call(Main.java:6)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
** Main stopped
Please take a look at Thread.UncaughtExceptionHandler
Better (alternative) way is to use Callable and Future to get the same result...
Use Callable instead of Thread, then you can call Future#get() which throws any exception that the Callable threw.
AtomicReference is also a solution to pass the error to the main thread .Is same approach like the one of Dan Cruz .
AtomicReference<Throwable> errorReference = new AtomicReference<>();
Thread thread = new Thread() {
public void run() {
throw new RuntimeException("TEST EXCEPTION");
}
};
thread.setUncaughtExceptionHandler((th, ex) -> {
errorReference.set(ex);
});
thread.start();
thread.join();
Throwable newThreadError= errorReference.get();
if (newThreadError!= null) {
throw newThreadError;
}
The only change is that instead of creating a volatile variable you can use AtomicReference which did same thing behind the scenes.
Currently you are catching only RuntimeException, a sub class of Exception. But your application may throw other sub-classes of Exception. Catch generic Exception in addition to RuntimeException
Since many of things have been changed on Threading front, use advanced java API.
Prefer advance java.util.concurrent API for multi-threading like ExecutorService or ThreadPoolExecutor.
You can customize your ThreadPoolExecutor to handle exceptions.
Example from oracle documentation page:
Override
protected void afterExecute(Runnable r,
Throwable t)
Method invoked upon completion of execution of the given Runnable. This method is invoked by the thread that executed the task. If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.
Example code:
class ExtendedExecutor extends ThreadPoolExecutor {
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
Usage:
ExtendedExecutor service = new ExtendedExecutor();
I have added one constructor on top of above code as:
public ExtendedExecutor() {
super(1,5,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
}
You can change this constructor to suit your requirement on number of threads.
ExtendedExecutor service = new ExtendedExecutor();
service.submit(<your Callable or Runnable implementation>);
Also from Java 8 you can write Dan Cruz answer as:
Thread t = new Thread(()->{
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException(); });
t.setUncaughtExceptionHandler((th, ex)-> log(String.format("Exception in thread %d id: %s", th.getId(), ex)));
t.start();
I faced the same issue ... little work around (only for implementation not anonymous objects ) ... we can declare the class level exception object as null ... then initialize it inside the catch block for run method ... if there was error in run method,this variable wont be null .. we can then have null check for this particular variable and if its not null then there was exception inside the thread execution.
class TestClass implements Runnable{
private Exception ex;
#Override
public void run() {
try{
//business code
}catch(Exception e){
ex=e;
}
}
public void checkForException() throws Exception {
if (ex!= null) {
throw ex;
}
}
}
call checkForException() after join()
Did you play around with setDefaultUncaughtExceptionHandler() and the alike methods of the Thread class? From the API: "By setting the default uncaught exception handler, an application can change the way in which uncaught exceptions are handled (such as logging to a specific device, or file) for those threads that would already accept whatever "default" behavior the system provided."
You might find the answer to your problem there... good luck! :-)
If you implement Thread.UncaughtExceptionHandler in class that starts the Threads, you can set and then rethrow the exception:
public final class ThreadStarter implements Thread.UncaughtExceptionHandler{
private volatile Throwable initException;
public void doSomeInit(){
Thread t = new Thread(){
#Override
public void run() {
throw new RuntimeException("UNCAUGHT");
}
};
t.setUncaughtExceptionHandler(this);
t.start();
t.join();
if (initException != null){
throw new RuntimeException(initException);
}
}
#Override
public void uncaughtException(Thread t, Throwable e) {
initException = e;
}
}
Which causes the following output:
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter.doSomeInit(ThreadStarter.java:24)
at com.gs.gss.ccsp.enrichments.ThreadStarter.main(ThreadStarter.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter$1.run(ThreadStarter.java:15)
Exception handling in Thread : By default run() method doesn’t throw any exception, so all checked exceptions inside the run method has to be caught and handled there only and for runtime exceptions we can use UncaughtExceptionHandler. UncaughtExceptionHandler is an interface provided by Java to handle exceptions in a Thread run method. So we can implement this interface and set back our implementing class back to Thread object using setUncaughtExceptionHandler() method. But this handler has to be set before we call start() on the tread.
if we don’t set uncaughtExceptionHandler then the Threads ThreadGroup acts as a handler.
public class FirstThread extends Thread {
int count = 0;
#Override
public void run() {
while (true) {
System.out.println("FirstThread doing something urgent, count : "
+ (count++));
throw new RuntimeException();
}
}
public static void main(String[] args) {
FirstThread t1 = new FirstThread();
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Exception thrown by %s with id : %d",
t.getName(), t.getId());
System.out.println("\n"+e.getClass());
}
});
t1.start();
}
}
Nice explanation given at http://coder2design.com/thread-creation/#exceptions
It is almost always wrong to extend Thread. I cannot state this strongly enough.
Multithreading Rule #1: Extending Thread is wrong.*
If you implement Runnable instead you will see your expected behaviour.
public class Test implements Runnable {
public static void main(String[] args) {
Test t = new Test();
try {
new Thread(t).start();
} catch (RuntimeException e) {
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run() {
try {
while (true) {
System.out.println("** Started");
Thread.sleep(2000);
throw new RuntimeException("exception from thread");
}
} catch (RuntimeException e) {
System.out.println("** RuntimeException from thread");
throw e;
} catch (InterruptedException e) {
}
}
}
produces;
Main stoped
** Started
** RuntimeException from threadException in thread "Thread-0" java.lang.RuntimeException: exception from thread
at Test.run(Test.java:23)
at java.lang.Thread.run(Thread.java:619)
* unless you want to change the way your application uses threads, which in 99.9% of cases you don't. If you think you are in the 0.1% of cases, please see rule #1.
My solution with RxJava:
#Test(expectedExceptions = TestException.class)
public void testGetNonexistentEntry() throws Exception
{
// using this to work around the limitation where the errors in onError (in subscribe method)
// cannot be thrown out to the main thread
AtomicReference<Exception> ex = new AtomicReference<>();
URI id = getRandomUri();
canonicalMedia.setId(id);
client.get(id.toString())
.subscribe(
m ->
fail("Should not be successful"),
e ->
ex.set(new TestException()));
for(int i = 0; i < 5; ++i)
{
if(ex.get() != null)
throw ex.get();
else
Thread.sleep(1000);
}
Assert.fail("Cannot find the exception to throw.");
}
For those who needs to stop all Threads running and re-run all of them when any one of them is stopped on an Exception:
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// could be any function
getStockHistory();
}
public void getStockHistory() {
// fill a list of symbol to be scrapped
List<String> symbolListNYSE = stockEntityRepository
.findByExchangeShortNameOnlySymbol(ContextRefreshExecutor.NYSE);
storeSymbolList(symbolListNYSE, ContextRefreshExecutor.NYSE);
}
private void storeSymbolList(List<String> symbolList, String exchange) {
int total = symbolList.size();
// I create a list of Thread
List<Thread> listThread = new ArrayList<Thread>();
// For each 1000 element of my scrapping ticker list I create a new Thread
for (int i = 0; i <= total; i += 1000) {
int l = i;
Thread t1 = new Thread() {
public void run() {
// just a service that store in DB my ticker list
storingService.getAndStoreStockPrice(symbolList, l, 1000,
MULTIPLE_STOCK_FILL, exchange);
}
};
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable exception) {
// stop thread if still running
thread.interrupt();
// go over every thread running and stop every one of them
listThread.stream().forEach(tread -> tread.interrupt());
// relaunch all the Thread via the main function
getStockHistory();
}
};
t1.start();
t1.setUncaughtExceptionHandler(h);
listThread.add(t1);
}
}
To sum up :
You have a main function that create multiple thread, each of them has UncaughtExceptionHandler which is trigger by any Exception inside of a thread. You add every Thread to a List. If a UncaughtExceptionHandler is trigger it will loop through the List, stop every Thread and relaunch the main function recreation all the Thread.
You cannot do this, since it doesn't really make sense. If you hadn't called t.join() then you main thread could be anywhere in the code when the t thread throws an exception.

Notify the calling method about the exception occured in thread

I am writing an Spring-mvc application.
I am executing task using ThreadPoolTaskExecutor.
I have below sample code.
MyClass.java
public class MyClass {
public void startProcess() {
ThreadPoolTaskExecutor taskExecutor = //Initializing
for (int i = 1; i <= 5; i++) {
taskExecutor.execute(new MyRunnable());
// I can call taskExecutor.submit(task); also, if required
}
}
}
MyRunnable.java
public class MyRunnable implements Runnable {
#Override
public void onRun() {
try {
//Code which generates exception like below
throw new Exception("Runtime Exception");
} catch (Exception e1) {
// log or throw the exception
}
}
}
I want to notify startProcess() about the exception occurred in MyRunnable's run method.
Can any one please guide me for this.
I found below links but it is not solving my problem.
Handling exceptions from Java ExecutorService tasks
http://java.dzone.com/articles/spring-async-and-exception
Thanks.
Edit:
One more question. If I am using #Async for asynchronous call to my some other method and If I want to check for the exception occured in async method then what should I do? As async method also returns future object.
Answer for #Async question I got from here
Instead of Runnable, implement Callable. A Callable can throw an exception, and when you retrieve the result of the Callable using a Future, you will get the exception thrown as an ExecutionException:
public class MyCallable implements Callable<Void> {
public Void call() throws Exception {
try {
//Code which generates exception like below
throw new Exception("Runtime Exception");
} catch (Exception e1) {
// log or throw the exception
}
return null; // To satisfy the method signature
}
}
In MyClass:
List<Future<Void>> futures = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
Future<Void> future = taskExecutor.submit(new MyCallable());
futures.add(future);
}
// After all tasks have started, now wait for all of them to complete (they run in parallel)
// and check if there were any exceptions
for (Future<Void> future : futures) {
try {
future.get();
} catch (ExecutionException e) {
// Access the exception thrown by the different thread.
e.getCause().printStackTrace();
}
}
You can add constructor with some listener to your Thread.
Like:
ExceptionListener:
public class ExceptionListener{
public void doSomething(long threadId,Exception e){
//...e.g., notify startProcess()
}
}
MyRunnable:
public class MyRunnable implements Runnable {
private ExceptionListener listener;
private MyRunnable(ExceptionListener exception) {
this.listener = listener;
}
#Override
public void run() {
//...
listener.doSomething(Thread.currentThread().getId(),new Exception("Runtime Exception"));
//...
}
}
startProcess():
public void startProcess() {
ThreadPoolTaskExecutor taskExecutor = //Initializing
ExceptionListener listener= new ExceptionListener();
for (int i = 1; i <= 5; i++) {
taskExecutor.execute(new MyRunnable(listener();
// I can call taskExecutor.submit(task); also, if required
}
}
Or, you can use Thread.UncaughtExceptionHandler, like described here.
edited.
Clarification:
if exception occurs, I have to stop my further execution of other
processes. So I want to catch or get notified about the exception in
startProcess method. – Naman Gala 1 hour ago
Answer:
I suppose that your worker thread will have while cycle. So you can just pass volatile
boolean to each thread and set it up to true or
false in case of exception, cycle condition will be this boolean
variable. – Maksym 58 mins ago

How to re-throw an exception to catch-block in another thread

I've code that looks like this:
public static void startService() {
try{
new Thread(new Runnable() {
#Override
public void run() {
throw new RuntimeException("Some exception");
}
}).start();
}catch (Exception e){
//Exception handling
}
}
How can I handle this exception in the catch() block in parrent thread?
UPD: This threads have to work asynchronous
You have several options to handle exceptions thrown by threads. One is to have a general uncaught exceptions handler:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
//log the exception or handle it here if possible
}
});
But it is difficult to link an exception caught that way with a specific thread.
Or you can use an ExecutorService instead of starting the thread manually:
ExecutorService executor = Executors.newCachedThreadPool();
Future<?> future = executor.submit(new Runnable() {
#Override
public void run() {
throw new RuntimeException("Some exception");
}
});
try {
future.get();
} catch (ExecutionException e) {
Throwable yourException = e.getCause(); //here you can access the exception
}
If you mean it is inside of Runnable's run() method then you will have to use another approach. Use Callable instead! Callable call() method allows you to return a value and throw an exception.
Please have a look here for an example on how to use Callable. Also, note that it is better to use a higher level api such as ExecutorService which manages the lifecycle of your threads and provides thread pooling. (included in the example)
you would have to use an Callable.
The thread.run method will never throw an exception since it is - well - executed in a different thread and in this was will not interfere with your calling thread.
if you execute a callable (by e.g. running it via an ExecutorService) you get a Future result which in turn will throw the given exception when calling the future.get() method.
Use throw statement in catch block.
public static void startService() {
try{
new Thread(new Runnable() {
#Override
public void run() {
}
}).start();
}catch (Exception e){
throw e;
}
}
Rethrowing an exception is simply adding throw e in the catch block

Can nested threads throw exceptions for parent thread?

I have a Controller class and a Monitor worker thread.
The controller thread looks something like this
public class ControllerA {
public void ControllerA(){
try{
doWork();
}
catch(OhNoException e){
//catch exception
}
public void doWork() throws OhNoException{
new Thread(new Runnable(){
public void run(){
//Needs to monitor resources of ControllerA,
//if things go wrong, it needs to throw OhNoException for its parent
}
}).start();
//do work here
}
}
Is such setup feasible? How do I throw exception to the outside of the thread?
How do I throw exception to the outside of the thread?
Couple ways you can do this. You can set a UncaughtExceptionHandler on the thread or you can use an ExecutorService.submit(Callable) and use the exception that you get from the Future.get().
The easiest way is to use the ExecutorService:
ExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
Future<Void> future = threadPool.submit(new Callable<Void>() {
public Void call() throws Exception {
// can throw OhNoException here
return null;
}
});
// you need to shut down the pool after submitting the last task
threadPool.shutdown();
try {
// this waits for your background task to finish, it throws if the task threw
future.get();
} catch (ExecutionException e) {
// this is the exception thrown by the call() which could be a OhNoException
Throwable cause = e.getCause();
if (cause instanceof OhNoException) {
throw (OhNoException)cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException)cause;
}
}
If you want to use the UncaughtExceptionHandler then you can do something like:
Thread thread = new Thread(...);
final AtomicReference throwableReference = new AtomicReference<Throwable>();
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
throwableReference.set(e);
}
});
thread.start();
thread.join();
Throwable throwable = throwableReference.get();
if (throwable != null) {
if (throwable instanceof OhNoException) {
throw (OhNoException)throwable;
} else if (throwable instanceof RuntimeException) {
throw (RuntimeException)throwable;
}
}
Runnable interface cannot throw checked exceptions or return values. In The Callable interface you can call any worker method that return values or throws exceptions. The main tasks of the monitor would be
To declare and initialize the future with the callable instance.
A getResult() method that can have a return future.get(); statement and should declare any checked exceptions in its throws clause for it to be handled by the calling code. In this way we dont have to return a null.

Categories