• Post Reply Bookmark Topic Watch Topic
  • New Topic

UncaughtExceptionHandler vs Throwable Handler  RSS feed

 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I have read in 'concurrency in practice' to use UncaughtExceptionHandler to catch all the run time exception or other exception which are not caught to avoid your application sudden death.

I am using the same in my application and want to log it in my log file whenever any exception comes and dont want to terminate the programme.

My problem is that i am successfully catching any exception through UncaughtExceptionHandler but after that my application hung. It doesnot do anything but not terminating as well. Control was with the class which implementing UncaughtExceptionHandler and not coming out of it after it makes entry into the file. example code is as below:




To overcome the same problem i am using Throwable handler instead of UncaughtExceptionHandler and making a log entry if any exception comes and it is working fine as it desired to be.

But i want to know why problem is coming with first option and which one is more elegant to use.
 
Vince Valentin
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Did you try adding a System.exit(0); to the end of your catch statement, after you do your logging?

Not actually sure if that would work but you could give it a shot.
 
Paweł Baczyński
Bartender
Posts: 2083
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Calling System.exit(0) will terminate entire JVM!
The whole point of having UncaughtExceptionHandler is allowing the program to continue even when encountering some uncaught exceptions...
 
Jaikiran Pai
Sheriff
Posts: 10447
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happens if you get rid of the logger from that implementation and just do a System.out.println(). The reason I ask that is to see if the problem is in the logger or some place else. Of course, this can also be figured out if you can get a thread dump when the program seems to be hung. Can you get one and post that here?
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Jaikiran It is working fine if i removed UncaughtExceptionHandler. As you suggested i also tried to use println instead of logger but it is working only once as logger was working. After that it struck and displays no output.

This was the error i got when i generated error first time after that it is not coming and application got hung after that..

Server is started
1. Start server
2. Stop server
Enter choice(1-2): 1Uncaught Exception received. Recieved error on Alarm Processor thread. java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.AbstractStringBuilder.substring(AbstractStringBuilder.java:877)
at java.lang.StringBuilder.substring(StringBuilder.java:72)
at fault_management.AlarmProcessor.processAlarm(AlarmProcessor.java:153)
at fault_management.AlarmProcessor.startAlarmProcessing(AlarmProcessor.java:86)
at fault_management.AlarmService$2.run(AlarmService.java:96)
at java.lang.Thread.run(Thread.java:679)

Also, How to take thread dump?
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i googled it and used jstack pid

and found following logs:

2014-04-28 15:54:58
Full thread dump OpenJDK 64-Bit Server VM (20.0-b12 mixed mode):

"Attach Listener" daemon prio=10 tid=0x00007f6d18001000 nid=0x571 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Low Memory Detector" daemon prio=10 tid=0x00007f6d4409e800 nid=0x142 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x00007f6d4409c000 nid=0x141 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x00007f6d44099000 nid=0x140 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00007f6d4408b000 nid=0x13f runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00007f6d44079000 nid=0x13e in Object.wait() [0x00007f6d40565000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ed8b1310> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
- locked <0x00000000ed8b1310> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

"Reference Handler" daemon prio=10 tid=0x00007f6d44077000 nid=0x13d in Object.wait() [0x00007f6d40666000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ed8b11e8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x00000000ed8b11e8> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0x00007f6d44009000 nid=0x137 runnable [0x00007f6d4bfc9000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:236)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:273)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
- locked <0x00000000ed8ba158> (a java.io.BufferedInputStream)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:282)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:324)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:176)
- locked <0x00000000edc89b98> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:100)
at java.util.Scanner.readInput(Scanner.java:797)
at java.util.Scanner.next(Scanner.java:1476)
at java.util.Scanner.nextInt(Scanner.java:2108)
at java.util.Scanner.nextInt(Scanner.java:2067)
at fault_management.FaultManagement.main(FaultManagement.java:49)

"VM Thread" prio=10 tid=0x00007f6d44070800 nid=0x13c runnable

"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f6d44013800 nid=0x138 runnable

"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f6d44015800 nid=0x139 runnable

"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f6d44017800 nid=0x13a runnable

"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f6d44019000 nid=0x13b runnable

"VM Periodic Task Thread" prio=10 tid=0x00007f6d440a9000 nid=0x143 waiting on condition

JNI global references: 885
 
Heena Agarwal
Ranch Hand
Posts: 262
4
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tushar Goel wrote:But i want to know why problem is coming with first option and which one is more elegant to use.


Hi Tushar,

I've been trying to work on your problem for my own learning. Following is what I think is the case.

An uncaught exception handler is not really the same thing as any other catch block. A catch block catches an exception and prevents the thread that threw the exception from terminating if the exception is successfully caught, i.e if the catch block does not result in another exception being thrown. An uncaught exception handler on the other hand is just a facility provided by the Thread class to enable the thread to do additional things before it terminates. Those additional things could be anything - like for example, sending an email to an admin, logging, starting a new Thread -- it really depends on your use case.

In case of worker threads like configurations, the worker thread has no idea of what kind of tasks it is going to run. Some tasks can be nicely coded, but the worker thread has no way of knowing that. So if a worker thread is supposed to execute say 10 tasks, and say task number 5 throws an uncaught RuntimeException, it could terminate the worker thread. This is not what you'd want. This is one of the cases where the uncaught exception handlers come in handy. I could have the uncaught exception handler start another worker thread to execute the remaining tasks. But this wouldn't happen just by implementing the Thread.UncaughtExceptionHandler interface and coding the uncaughtException method to just log the exception. Unlike a catch block, an uncaught exception handler does not prevent the original thread from terminating.

The JLS says the following about the UncaughtExceptionHandlers.

JLS wrote:During the process of throwing an exception, the Java Virtual Machine abruptly completes, one by one, any expressions, statements, method and constructor invocations, initializers, and field initialization expressions that have begun but not completed execution in the current thread. This process continues until a handler is found that indicates that it handles that particular exception by naming the class of the exception or a superclass of the class of the exception (§11.2). If no such handler is found, then the exception may be handled by one of a hierarchy of uncaught exception handlers (§11.3) - thus every effort is made to avoid letting an exception go unhandled.


JLS wrote:If no catch clause that can handle an exception can be found, then the current thread (the thread that encountered the exception) is terminated. Before termination, all finally clauses are executed and the uncaught exception is handled according to the following rules:

If the current thread has an uncaught exception handler set, then that handler is executed.

Otherwise, the method uncaughtException is invoked for the ThreadGroup that is the parent of the current thread. If the ThreadGroup and its parent ThreadGroups do not override uncaughtException, then the default handler's uncaughtException method is invoked.


Let us consider an example. I have a Task class as follows.



Following is my worker thread's implementation. MyRunner is a Runnable that executes tasks in a list within its run method.



If I run the MyRunner class with the commented part as commented, I get the following output.

Thread-0
Thread-0 is running task number 0
Exception in thread "Thread-0" java.lang.RuntimeException: Some stupid RE
at threadandsynchronization.Task.execute(Task.java:28)
at threadandsynchronization.MyRunner.run(MyRunner.java:36)
at java.lang.Thread.run(Unknown Source)


So an exception in the 1st task has terminated my worker and hence tasks 1 till 9 could not run. Obviously if the Task class had a catch-all, my worker thread would not get terminated, but a worker thread does not know if the task is a well planned task. It should prepare for failures in the called code.

Now if I uncomment the UnCaughtExceptionHandler parts, I get the following output.

Thread-0
Thread-0 is running task number 0
Uncaught Exception received. Recieved error on Thread-0 thread. Some stupid RE
Thread-1
Thread-1 is running task number 1
After catch in the task 1
Thread-1is done executing task 1
Thread-1
Thread-1 is running task number 2
After catch in the task 2
Thread-1is done executing task 2
Thread-1
Thread-1 is running task number 3
After catch in the task 3
Thread-1is done executing task 3
Thread-1
Thread-1 is running task number 4
After catch in the task 4
Thread-1is done executing task 4
Thread-1
Thread-1 is running task number 5
Uncaught Exception received. Recieved error on Thread-1 thread. Some stupid RE
Thread-2
Thread-2 is running task number 6
After catch in the task 6
Thread-2is done executing task 6
Thread-2
Thread-2 is running task number 7
After catch in the task 7
Thread-2is done executing task 7
Thread-2
Thread-2 is running task number 8
After catch in the task 8
Thread-2is done executing task 8
Thread-2
Thread-2 is running task number 9
After catch in the task 9
Thread-2is done executing task 9
After all tasks have started


In your first case, you are just logging the exception as a part of the Uncaught exception handler. This will not prevent the thread that is calling the startServer method from terminating.

Obviously you need to analyze why you are getting the StringIndexOutOfBoundException. That is the real problem you need to solve. But to think that an uncaught exception handler that just logs an exception can catch an exception just like a catch block does would be wrong in my opinion.

To answer the question, which of the two things are better, I think that an uncaught exception handler and a catch-all block in the task class are not mutually exclusive. Worker threads execute tasks generally through an abstraction and since tasks are unknown kind of things to worker threads, uncaught exception handlers are good regardless of whether the task has a catch-all block.

I don't know if a catch-all block in the Task class is a good idea. Obviously the catch-all block would make sure the failure condition will not cause the invoking thread to terminate, which is what well planned tasks do. But you don't require a catch-all to catch ( and handle in the correct way ) all the likely failure conditions. Also catch-all's are risky. I mean you never know for how long you are still using the corrupted data till you see a failure later. But that's just one of the things ( significant things ) and it really depends on your implementation and the possibilities with your use case.
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Heena for detailed explanation..

I got your point that UncaughtExceptionHandler is used to do some important work before terminating the thread like logging . sending mail, free resources etc, In particular to my problem i see whenever any problems comes it make a log entry and got terminate.
Also as i am using single thread in consumer and multiple thread in producer so after terminating no new thread is generated and hence it got struck as consumer dead but producer not. I finally realized this...

Regarding my another question related to catch all or us throwable i think it is matter of choice. Because in either case i want to log the entry and gracefully make thread died which can be done either way.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!