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;
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.
I have a common project with some shared code that is being used in another project. I'm trying to convert/map the exception from the common project CommonException to a new type of Exception let's call it SuperAwesomeException.
The aim is to have a generic way of handling all custom exceptions in the project.
I've attempted to do this using an UncaughtExceptionHandler. This seems to work when running the project but not from within JUnit, since that wraps each test in a try/catch block as described here.
public final class ExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread thread, Throwable exception) {
if (exception instanceof CommonException) {
throw new SuperAwesomeException(exception.getMessage());
}
if (exception instanceof SuperAwesomeException) {
throw new CommonException(exception.getMessage());
}
else {
System.out.println("ERROR! caught some other exception I don't really care about");
System.out.println("Not doing anything");
}
}
}
Is there another way I can map from one Exception to another or can I somehow tell JUnit not to catch certain exceptions and check the Exception is mapped to the correct one?
UPDATE - How I initially tried to write the Test:
public class ClassThatThrowsException {
ClassThatThrowsException() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
}
public void doSomething() {
throw new CommonException("Something boring blew up!");
}
}
public class ClassThatThrowsExceptionTest {
#Test(expected=SuperAwesomeException.class)
public void testAwesome() {
ClassThatThrowsException c = new ClassThatThrowsException();
c.doSomething();
}
}
which throws:
java.lang.Exception: Unexpected exception, expected<SuperAwesomeException> but was<CommonException>
The problem is: when you are using JUnit, the framework will catch your exception. Therefore the uncaught exception handler isn't called in the first place!
See here for more details.
Thus, you have to do two things:
A) write tests that make sure that your exception handler implementation works as desired
#Test(expected=SuperAwesomeException.class)
public void testAwesome() {
new ExceptionHandler().uncaughtException(null, new CommonException("whatever"));
}
B) thest the plumbing - you want to make sure that this specific uncaught handler gets actually set by your code:
#Test
public void testDefaultHandlerIsSet() {
// creating a new instance should update the handler!
new ClassThatThrowsException();
Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
assertThat(handler, not(nullValue()));
assertThat(handler, instanceOf(ExceptionHandler.class));
}
Finally - please note: you should not just do new XException(oldException.getMessage). Rather go for new XException("some message, oldException).
In other words: you got a cause here; so you better use the incoming exception as cause within the new one you intend to throw. Otherwise you loose all stack trace information.
I am facing problem while I am trying to call another program from Task3 program and try to execute it on scheduled time. Getting exception at line 14 as below.
Please let me know where I am going wrong in call program from run method of Runnable interface.
Task3.java:14: error: unreported exception Exception; must be caught or declar
to be thrown
Mult.main(new String[0]);
import java.util.Timer;
import java.util.TimerTask;
public class Task3 {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
#Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
Mult.main(new String[0]);
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
Mult.main has a throws clause that includes a checked exception, so for the code to be accepted by the compiler you'd need to add that exception to the throws clause of the run method or catch the exception. You can't add that exception to the throws clause however, since you override TimerTask.run, which declares no exceptions.
The only remaining opitions are catching that error or change Mult.main to not throw any exceptions that are not subclasses of RuntimeException. You could e.g. catch the exception and throw a runtime exception or do something else, if an exception occurs:
TimerTask task = new TimerTask() {
#Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
try {
Mult.main(new String[0]);
} catch (Exception ex) {
// handle the exception,
// in this case by throwing a RuntimeException with ex as cause
throw new IllegalStateException("I didn't expect a exception.", ex);
}
}
};
This is a compile-time error. Your method Mult.main() can throw an Exception.
Surround it with try/catch to handle error, e.g.
try {
Mult.main(new String[0]);
} catch (Exception e) {
// Handle your error here
}
It's hard to tell without more code, but it looks like:
Mult.main(...) is defined as throwing an exception, in which case the code that calls must handle the exception.
Either:
Wrap the call to Mult.main(...) in a try-catch block, or
Define Task3.main(...) to throw Exception as well
P.S. or maybe it's timer.scheduleAtFixedRate(...), can't really tell without line numbers
I'm beginner in Java and Android. My problem is when I use setDefaultUncaughtExceptionHandler in my code, some functions still need a try/catch block surrounding it, but I want throw all my exceptions to UncaughtException thread.
public class MyAlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtException(context));
try
{
String imageURL = MyWebService.readFeed();
DownloadAndSet.downloadFile(imageURL);
}
catch(Throwable e)
{
throw new RuntimeException(e);
}
Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show();
}
}
Java distinguishes checked and unchecked exceptions. Checked Exceptions have to be caught, no matter what.
Correction: Or you have to add the throws clause to the method. This postpones the urge to catch that exception to the caller of your method.
If you want them to be handled in the UncaughtExceptionHandler, you can "forward" them:
try{
// blah "throws some checked exception type"
} catch ( Throwable e ) {
// throw e; <- This will not work :( unless you add the "throws" clause.
throw new RuntimeException(e);
}
Unfortunately, just throwing the same Exception won't work, because you'd have to add the throws clause, which you do not want. You'll have to wrap it in a RuntimeException.
All checked exceptions in your code must be caught.
Further reading on checked vs unchecked exceptions:
http://www.javapractices.com/topic/TopicAction.do?Id=129
http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
When you call a method that throws an exception, requires you to either handle the exception using try/catch or throw the same exception.
As you don't want to handle the exception in your code and want all exceptions to be handled by your Default Exception handler so you need to add throws to all your methods where you don't want to catch the exception.
The documentation says:
Set the default handler invoked when a thread abruptly terminates due to an uncaught exception, and no other handler has been defined for that thread.
It doesn't relate to exceptions you have to catch. An example of an exception you have to catch/throw is IOException. An example of an exception you don't is NullPointerException.
So if your code causes a NullPointerException, the default handler will deal with it. If your code (potentially) causes an IOException, you have to deal with it then and there (either by catching or throwing).
What I have always done in my programs is create a exception handler method and call it every time I make a try/catch block. Many times I have had Thread.sleep() methods and I just send the exception to a common place to do "global" handling. In your global exception handler, you can also refer to this method.
Keep in mind that you might not always want to use this method because things like file streams might throw errors if a file already exists and you would want to take a different approach such as naming it something else than just stopping the program.
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
catchException(e);
}
});
try {
Thread.sleep(1000);// Just an example of a possible exception thrower
}
catch (InterruptedException e) {
catchException(e);
}
}
public static void catchException(Throwable e) {
// Deal with the exception here
System.out.println("Oh no! You broke the program!!!");
System.out.println("Here is the error btw: " + e.getMessage());
}
If you are using Eclipse, you can set the default automatic code generation for try/catch blocks to automatically include this method:
You can also set project specific settings if you don't want this behaviour for all of your projects.
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
}