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;
}
}
Related
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.
I am using the class FutureTask that takes a Callable object in his constructor and calls call() from inside his run method like this:
public void run() { //Thread
while(true) {
try {
FutureTask<String> task = taskQueue.take();
task.run(); //executing call() somehow
}
catch (InterruptedException e) {
System.out.println("Thread finishing from interrupt()...");
break; //I would like to break the loop if I receive the exception
}
}
}
My call implementation is like this:
#Override
public String call() throws InterruptedException {
Thread.sleep(taskTime);
//After calling interrupt() on this thread an InterruptedException is thrown
return "someString"; // this is not reached
}
But I think that the run method is swallowing the exception since I can not reach the catch block. Do you have any ideas?
I call thread.interrupt(); with thread being the thread running run().
To be cleared: when task.run() is running, it is executing Thread.sleep(taskTime); which correctly throws the exception, but the run() method seems to swallow it.
The problem is this: I have a library class (that I can not modify) which takes an object to run a particular method which could throw an exception. This library class acts like a wrapper and it seems like it swallows the exception instead of propagating it. What would you do?
Suppose I have a class and a method
class A {
void foo() throws Exception() {
...
}
}
Now I would like to call foo for each instance of A delivered by a stream like:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Question: How do I properly handle the exception? The code does not compile on my machine because I do not handle the possible exceptions that can be thrown by foo(). The throws Exception of bar seems to be useless here. Why is that?
You need to wrap your method call into another one, where you do not throw checked exceptions. You can still throw anything that is a subclass of RuntimeException.
A normal wrapping idiom is something like:
private void safeFoo(final A a) {
try {
a.foo();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
(Supertype exception Exception is only used as example, never try to catch it yourself)
Then you can call it with: as.forEach(this::safeFoo).
If all you want is to invoke foo, and you prefer to propagate the exception as is (without wrapping), you can also just use Java's for loop instead (after turning the Stream into an Iterable with some trickery):
for (A a : (Iterable<A>) as::iterator) {
a.foo();
}
This is, at least, what I do in my JUnit tests, where I don't want to go through the trouble of wrapping my checked exceptions (and in fact prefer my tests to throw the unwrapped original ones)
This question may be a little old, but because I think the "right" answer here is only one way which can lead to some issues hidden Issues later in your code. Even if there is a little Controversy, Checked Exceptions exist for a reason.
The most elegant way in my opinion can you find was given by Misha here Aggregate runtime exceptions in Java 8 streams
by just performing the actions in "futures". So you can run all the working parts and collect not working Exceptions as a single one. Otherwise you could collect them all in a List and process them later.
A similar approach comes from Benji Weber. He suggests to create an own type to collect working and not working parts.
Depending on what you really want to achieve a simple mapping between the input values and Output Values occurred Exceptions may also work for you.
If you don't like any of these ways consider using (depending on the Original Exception) at least an own exception.
You might want to do one of the following:
propagate checked exception,
wrap it and propagate unchecked exception, or
catch the exception and stop propagation.
Several libraries let you do that easily. Example below is written using my NoException library.
// Propagate checked exception
as.forEach(Exceptions.sneak().consumer(A::foo));
// Wrap and propagate unchecked exception
as.forEach(Exceptions.wrap().consumer(A::foo));
as.forEach(Exceptions.wrap(MyUncheckedException::new).consumer(A::foo));
// Catch the exception and stop propagation (using logging handler for example)
as.forEach(Exceptions.log().consumer(Exceptions.sneak().consumer(A::foo)));
I suggest to use Google Guava Throwables class
propagate(Throwable throwable)
Propagates throwable as-is if it is an
instance of RuntimeException or Error, or else as a last resort, wraps
it in a RuntimeException and then propagates.**
void bar() {
Stream<A> as = ...
as.forEach(a -> {
try {
a.foo()
} catch(Exception e) {
throw Throwables.propagate(e);
}
});
}
UPDATE:
Now that it is deprecated use:
void bar() {
Stream<A> as = ...
as.forEach(a -> {
try {
a.foo()
} catch(Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
});
}
You can wrap and unwrap exceptions this way.
class A {
void foo() throws Exception {
throw new Exception();
}
};
interface Task {
void run() throws Exception;
}
static class TaskException extends RuntimeException {
private static final long serialVersionUID = 1L;
public TaskException(Exception e) {
super(e);
}
}
void bar() throws Exception {
Stream<A> as = Stream.generate(()->new A());
try {
as.forEach(a -> wrapException(() -> a.foo())); // or a::foo instead of () -> a.foo()
} catch (TaskException e) {
throw (Exception)e.getCause();
}
}
static void wrapException(Task task) {
try {
task.run();
} catch (Exception e) {
throw new TaskException(e);
}
}
More readable way:
class A {
void foo() throws MyException() {
...
}
}
Just hide it in a RuntimeException to get it past forEach()
void bar() throws MyException {
Stream<A> as = ...
try {
as.forEach(a -> {
try {
a.foo();
} catch(MyException e) {
throw new RuntimeException(e);
}
});
} catch(RuntimeException e) {
throw (MyException) e.getCause();
}
}
Although at this point I won't hold against someone if they say skip the streams and go with a for loop, unless:
you're not creating your stream using Collection.stream(), i.e. not straight forward translation to a for loop.
you're trying to use parallelstream()
I am implementing an interface which throws IOException. In my implementation, I call another method which can block, and therefore throw InterruptedException.
Context:
I want to end the treatment if I am interrupted;
this is not a thread I created myself.
My current idea is to do as such (skeleton code):
#Override
public void implementedMethod()
throws IOException
{
try {
methodThatBlocks();
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
throw new IOException();
}
}
is that the correct way? Or should I just throw and not .interrupt()?
Yes, you should call interrupt() to let the calling code know that the thread has been interrupted. If you don't do it, since the InterruptedException clears it, the calling code will have no way to know about the interruption and won't stop running although it should.
Let me quote Java Concurrency in Practice:
Restore the interrupt. Sometimes you cannot throw InterruptedException, for instance when your code is part of a Runnable. In these situations, you must catch InterruptedException and restore the interrupted status by calling interrupt on the current thread, so that code higher up the call stack can see that an interrupt was issued,
as demonstrated in Listing 5.10.
public class TaskRunnable implements Runnable {
BlockingQueue<Task> queue;
...
public void run() {
try {
processTask(queue.take());
} catch (InterruptedException e) {
// restore interrupted status
Thread.currentThread().interrupt();
}
}
}
Of course not. The thread is already unblocked and running. In the code that is about to throw an exception. What would be the point?
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.