I have multiple methods running concurrently on different threads. If an exception occurs and isn't handled on any of the threads, I want it to propagate back to the calling method (see example below).
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(3);
pool.execute(new Thread1Class());//Thread 1 of many
//...
}
}
class Thread1Class implements Runnable{
#Override
public void run() {
try {
throw new InterruptedException(); //How do I propogate this to the main method?
} catch (InterruptedException e) {
System.out.println("An unchecked exception was caught here");
}
}
}
The threads must implement Runnable since Callable will block the threads from running concurrently.
I followed the method of Overriding protected void afterExecute(Runnable r, Throwable t) shown as the accepted answer here: Handling exceptions from Java ExecutorService tasks. If I understand correct, this solution will only handle unchecked exceptions. How should I deal with the checked exceptions?
If I understand correct, this solution will only handle unchecked exceptions. How should I deal with the checked exceptions
No, the afterExecute(Runnable, Throwable) would catch any RuntimeException or checked exception. According to the docs at https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html
If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.
Edit:
Sorry for the misunderstanding,
If you want to propagate the checked exception to the caller, you would need to wrap it in a RuntimeException
InterruptedException a;
throw new RuntimeException("wrapped", a);
The executor:
protected void afterExecute(Runnable r, Throwable t){
Throwable root = t.getCause();
}
Or you could create your own runtime exception type.
Related
#Override
Public class example {
void test {
try {
someMethod(); //This throws TimeoutException
} catch (TimeoutException ex) {
throw new TimeoutException(ex); //It doesn't throw error if I replace this with throw new RuntimeException(ex)
} }
}
The above example gives an error as 'throw new TimeoutException(ex)' as "TimeoutException(java.lang.string) in java.util.concurrent.TimeoutException cannot be applied to (java.util.concurrent.TimeoutException)".
But it doesn't throw an error if I replace it with 'throw new RuntimeException(ex)';
TimeoutException doesn't have a constructor that accepts a TimeoutException as an argument of the form TimeoutException(TimeoutException cause) or similar.
You can instead:
TimeoutException localtoe=new TimeoutException("test failed");
localtoe.initCause(ex);
throw localtoe;
Or equally:
throw new TimeoutException("test failed").initCause(ex);
initCause() may only be called once and only if cause wasn't set by a constructor. It's a funny little method that acts like a constructor after-thought(*).
There's nothing necessarily wrong with wrapping an exception as the cause of an exception.
Suppose testFunction() connects and then performs some operation.
You might want to throw an exception with message "connection failed in testFunction" and another "operation failed in testFunction" depending on what sub-step failed.
But if you don't need to provide so much detail you can just throw ex or let the method unwind without itself catching anything.
Here's a little example:
import java.util.concurrent.TimeoutException;
class Example{
private static void connect() throws TimeoutException {
//Dummy connection that just fails...
throw new TimeoutException("connection failed");
}
private static void process() throws TimeoutException {
try {
connect();
}catch(TimeoutException toe){
TimeoutException toeout=new TimeoutException("process failed because connection failed.");
toeout.initCause(toe);
throw toeout;
}
//Code for when connection succeeds...
}
public static void main (String[] args) throws java.lang.Exception
{
try{
process();
}catch(TimeoutException toe){
System.out.println(toe);
}
}
}
Expected output:
java.util.concurrent.TimeoutException: process failed because connection failed.
(*) initCause() looks like an after-thought and is somewhat. It was added to Java 1.4 in 2002. The documentation talks about 'legacy' constructors. Rather than double up the number of constuctors (to add one with a Throwable cause argument) it appears it was decided to allow this as bolt-on initialization.
It's debatable whether that was the best solution.
Things I observed in your question
you are trying to call a method directly from class in a try cache block. which is wrong you have to create method and call it from that
you want to throw an exception. SO you have to throw it method level from where you are calling it
please find the demo solution below :
public class example {
public void testFunction() throws TimeoutException {
try {
someFunction();
} catch (TimeoutException ex) {
throw ex;
}
}
public void someFunction() throws TimeoutException {
}
}
Java has 2 categories of exceptions: checked and unchecked. Checked exception (usually subclasses of Exception) must be declared in function signatures, while unchecked ones (usually subclasses of RuntimeException) must not.
TimeoutException is a checked exception. When it could be thrown from a method that does not declare it, you have 2 options:
declare it in the signature:
public void func1() throws TimeoutException {
somefunction();
}
clean and simple but it can be problemetic is func1 is an override of a function not declared to throw this exception, of it it is called from another function (suppose from a framework) that does not declare it either
hide it in an unchecked exception
public void func1() {
try {
somefunction();
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}
you lose the declarative part (checked exceptions exist for that reason), but at least it allows you to call it from function not declaring it.
You have roughly three options here:
Rethrow the same exception: `throw ex;'
Throw a new TimeoutException and lose the stack trace: throw new TimeoutException(ex.getMessage());
Throw an exception of another type, such as RuntimeException.
Each of these options have advantages and drawbacks, you decide.
UPDATE (thanks to #Mark Rottenveel)
Point 2 could be rewritten: throw new TimeoutException(ex.getMessage()).initCause(ex); to keep the link to the original exception.
Can anyone please give me information about it. I cant really uderstand the type of this Exception.
Thank you
public class ValidationException extends Exception{
public ValidationException(){
super("There was a problem when validating data");
}
public ValidationException(String message){
super(message);
}
public ValidationException(String message, Throwable throwable){
super(message, throwable);
}
public ValidationException(Throwable throwable){
super(throwable);
}
}
It is a "runtime exception" in the (fatuous) sense that it is an exception that occurs at runtime. But that is true for all Java exceptions ... apart from bugs in the compiler, etcetera.
It is not a subclass of RuntimeException. You have declared it as a subclass of Exception and Exception is not a subclass of RuntimeException. (In fact, the reverse is true: RuntimeException is a subclass of Exception!)
It is a checked exception because it is not a subclass of RuntimeException (or Error).
Since it is a checked exception, the Java rules about checked exceptions apply. For example, any method that throws or propagates1 your exception must declare that it throws this exception, or an exception that is a superclass of this exception.
1 - Technically, the JLS describes this as an abnormal termination of the method body with this exception as the abnormal termination reason.
The main difference between Exception, and RuntimeException is that we need to wrap a Exception in a try/catch block. A RuntimeException does not need to be caught, but it is just as lethal as an Exception.
public class Main{
public static void main(String[] args) {
Thread.currentThread().setUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Uncaught Exception " + e);
}
});
try{
throwException();
}catch(Exception e){
System.out.println("Caught Exception " + e);
}
try{
throwRuntimeException();
}catch(Exception e){
System.out.println("Caught RuntimeException " + e);
}
//unchecked, no need to wrap int try/catch
throwRuntimeException();
}
public static void throwException() throws Exception {
throw new Exception();
}
public static void throwRuntimeException() {
throw new RuntimeException();
}
}
Take this example above. The output is this:
Caught Exception java.lang.Exception
Caught RuntimeException java.lang.RuntimeException
Uncaught Exception java.lang.RuntimeException
As you can tell, the call to throwRuntimeException() gets thrown, and since there is no try/catch block it has no idea how to handle it. This crashes the thread and since there is an UncaughtExceptionHandler it gets called.
Then there is also Error which I won't go into since I don't know much about it besides that JVM throws it. OutOfMemoryError is an example.
I am using ExecutorService and Callable in Java. The class implementing Callable does some IO work on the filesystem. How do I stop the execution of a callable and exit from it, if an Exception occurs?
This is an example class implementing Callable that has two methods, foo1() and foo2()
public class MyCallable<Object> implements Callable<Object> {
public Object call() throws IOException, SQLException {
// method 1 , could throw IOException
foo1();
// method 2 , could throw SQLException
foo2();
return null;
}
}
This is the example execution service class. It can deal with exceptions occurred during the parallel processing through the futures object.
public class MyExecutorService {
ExecutorService listProcessor;
listProcessor = Executors.newFixedThreadPool(2);
List<Callable<Object>> callableTodo = new ArrayList<Callable<Object>>();
// add the callables to the todo list
callableTodo.add(new MyCallable<Object>());
callableTodo.add(new MyCallable<Object>());
// start the threads
List<Future<Object>> futures = listProcessor.invokeAll(callableTodo);
listProcessor.shutdown();
listProcessor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
// futures now holds possible exceptions
for (Future<Object> future : futures) {
try {
future.get();
} catch (ExecutionException e) {
// process the exception
}
}
}
But I would like to immediately let the MyCallable stop if for example a IOException occurs in foo1(), and not let it continue with foo2();
EDIT: Also, if an unchecked exception such as a RuntimeException occurs in foo1(), MyCallable also needs to stop.
The signature of Callable<V>'s call method is
V call() throws Exception
and its description is
Computes a result, or throws an exception if unable to do so.
In other words, just don't catch the IOException. If you don't catch it, then execution stops and the exception is passed up a level.
Note: this only works for non-RuntimeExceptions if the method is marked as throwing an exception type, which call is marked as doing because it's declared as throws Exception.
As you're already aware, Future's .get method will throw an ExecutionException if the Callable throws an exception.
It is sayed that the run does't throw Handled Exceptions. JVM simply ignores them. So I threw UnHandled Exception (ArithmeticException). But the same thing happened for it as well.
I know that it is rediculous to try to catch the excpetion from a thread that has been started by the catch clause marked as XXX. Because the excution may already passed that line.
But I wanna know why java allows run to throw Unhanlded Exception while restricting Handled ones and what is happening additionally when run() throwing Unhandled Exception?
Parent Thread
public class Parent {
public static void main(String[] args) {
Child child = new Child();
Thread chThread = new Thread(child);
try {
chThread.start();
} catch (Exception e) { // XXX mark
System.err.println("XXX");
e.printStackTrace();
}
}
Child Thread
public class Child implements Runnable {
#Override
public void run() throws ArithmeticException{
method0(); // line 8
}
public void method0(){
int i = 0/0; // line 12
}
}
java.lang.Thread
public class Thread implements Runnable {
public void run() {
if (target != null) {
target.run(); // line 619
}
}
}
StackTrace
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at seperateStacksPerThread.Child.method0(Child.java:12)
at seperateStacksPerThread.Child.run(Child.java:8)
at java.lang.Thread.run(Thread.java:619)
The signature of run() does not include a checked exception. As a result you can not override it to throw a checked exception (when you override you can never be more restrictive).
But throwing an unchecked exception is allowed as it is not part of the signature (no one is required to catch it).
When you throw the arithmetic exception it is part of the stack trace of a different thread.
Notice that it says:
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
And not: Exception in thread "main" java.lang.ArithmeticException: / by zero
Now why are checked exceptions not allowed, it is a design decision and I think it is because no one can catch them anyway as a thread is a separate flow of excecution.
Firstly, all methods may throw unchecked exceptions.
Next, the simple reason run() doesn't throw checked exceptions is there's no one there to catch them! The method is called from within the started thread as its "main" method - it's the top level entry point. There's nothing above it to deal with an exception, so there's no point in declaring a method that throws an exceptions.
Hey, I'm writing a network application, in which I read packets of some custom binary format. And I'm starting a background thread to wait for incoming data. The problem is, that the compiler doesn't let me to put any code throwing (checked) exceptions into run(). It says:
run() in (...).Listener cannot implement run() in java.lang.Runnable; overridden method does not throw java.io.IOException
I want the exception to kill the thread, and let it be caught somewhere in the parent thread. Is this possible to achieve or do I have to handle every exception inside the thread?
To be able to send the exception to the parent thread, you can put your background thread in a Callable (it allows throwing also checked exceptions) which you then pass to the submit method of some Executor. The submit method will return a Future which you can then use to get the exception (its get method will throw an ExecutionException which contains the original exception).
Caveat: this may not meet your needs if you have to use the exception mechanism.
If I understand you correctly, you don't actually need the exception to be checked (you've accepted the answer suggesting an unchecked exception) so would a simple listener pattern be more appropriate?
The listener could live in the parent thread, and when you've caught the checked exception in the child thread, you could simply notify the listener.
This means that you have a way of exposing that this will happen (through public methods), and will be able to pass more information than an exception will allow. But it does mean there will be a coupling (albeit a loose one) between the parent and the child thread. It would depend in your specific situation whether this would have a benefit over wrapping the checked exception with an unchecked one.
Here's a simple example (some code borrowed from another answer):
public class ThingRunnable implements Runnable {
private SomeListenerType listener;
// assign listener somewhere
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket();
}
} catch(Exception e) {
listener.notifyThatDarnedExceptionHappened(...);
}
}
}
The coupling comes from an object in the parent thread having to be of type SomeListenerType.
This answer is based on Esko Luontola one but it provides a working example.
Unlike the run() method of the Runnable interface the call() method of Callable allows to throw some exceptions. Here is an implementation example :
public class MyTask implements Callable<Integer> {
private int numerator;
private int denominator;
public MyTask(int n, int d) {
this.numerator = n;
this.denominator = d;
}
#Override
// The call method may throw an exception
public Integer call() throws Exception {
Thread.sleep(1000);
if (denominator == 0) {
throw new Exception("cannot devide by zero");
} else {
return numerator / denominator;
}
}
}
Executor provides a mechanism to run a Callable inside a thread and to handle any kind of exceptions :
public class Main {
public static void main(String[] args) {
// Build a task and an executor
MyTask task = new MyTask(2, 0);
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
try {
// Start task on another thread
Future<Integer> futureResult = threadExecutor.submit(task);
// While task is running you can do asynchronous operations
System.out.println("Something that doesn't need the tasks result");
// Now wait until the result is available
int result = futureResult.get();
System.out.println("The result is " + result);
} catch (ExecutionException e) {
// Handle the exception thrown by the child thread
if (e.getMessage().contains("cannot devide by zero"))
System.out.println("error in child thread caused by zero division");
} catch (InterruptedException e) {
// This exception is thrown if the child thread is interrupted.
e.printStackTrace();
}
}
}
What I do is to catch the exception in the thread and store it as a member variable of the Runnable. This exception is then exposed via a getter on the Runnable. I then scan all the threads from the parent to see if any had exceptions, and take the appropriate action.
If you really cannot do anything useful when the exception is raised you can wrap the checked exception in a RuntimeException.
try {
// stuff
} catch (CheckedException yourCheckedException) {
throw new RuntimeException("Something to explain what is happening", yourCheckedException);
}
the thread can't throw the exception to any other thread (nor to the main thread). and you cannot make the inherited run() method throw any checked exceptions since you can only throw less than the inherited code, not more.
If your thread's code throw a RuntimeExpection, you doesn't need to add run() throw Exception.
But use this solution only when appropriate because this can be a bad pratice:
http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html
Any RuntimeException or unchecked Exception can help you. Maybe you'll need to create your own RuntimeException
On the assumption that your code is in some kind of loop, you'd write:
public class ThingRunnable implements Runnable {
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket()
}
} catch(Exception e) {
System.out.println("Runnable terminating with exception" + e );
}
}
}
The exception will automatically break you out of your loop, and at the end of the run() method, the thread will stop.
Use this Runnable to create your Thread:
public abstract class TryRunner implements Runnable{
protected abstract void tryToRun();
protected void onException(Exception e){}
#Override
final public void run() {
try{ tryToRun(); }catch(Exception e){ e.printStackTrace(); onException(e); }
}
}
Wrapping your exception inside a RuntimeException seems to do the trick.
someMethod() throws IOException
{
try
{
new Thread(() ->
{
try
{
throw new IOException("a checked exception thrown from within a running thread");
}
catch(IOException ex)
{
throw new RuntimeException("a wrapper exception", ex); // wrap the checked exception inside an unchecked exception and throw it
}
}).start();
}
catch(RuntimeException ex) // catch the wrapped exception sent from within the thread
{
if(ex.getCause() instanceof IOException)
throw ex.getCause; // unwrap the checked exception using getCause method and use it however you need
else
throw ex;
}
}