I'm unsure why the uncaughtException method is not being invoke.
static
{
/**
* Register a logger for unhandled exceptions.
*/
Thread.UncaughtExceptionHandler globalExceptionHandler = new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("handle exception."); // can also set bp here that is not hit.
}
};
Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
Thread.currentThread().setUncaughtExceptionHandler(globalExceptionHandler);
/**
* Register gateway listen port.
*/
try
{
// some stuff that raises an IOException
}
catch (IOException e)
{
System.out.println("Throwing exception");
throw new RuntimeException(e);
}
}
The program output is:
Throwing exception
java.lang.ExceptionInInitializerError
Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: blah.jks
(The system cannot find the file specified)
...some stack trace...
Exception in thread "main"
Process finished with exit code 1
The RuntimeException being raised from a static initializer, it happens when your main class is loaded. It is then caught by the system class loader, which wraps it into an ExceptionInInitializerError, then exits from the JVM. Since the exception is caught, your default uncaught exception handler is never invoked.
Your code is throwing an IOException, and your catch catches an IOException. The IOException is caught and handled. IIRC the UncaughtExceptionHandler only deals with uncaught exception from within normal code, not from within a catch. Try changing your catch temporarily to catch some other exception, and see what happens. Don't forget to change it back afterwards!
Your code is in static block. Unless on very rare case of JVM implemenation ( if any), static block is not where you should handle any errors or exceptions if possible. This is because you don't have that much of control on the execution of static block ( unless you have dynamic class loader), which is pretty rare.
So if it is fair, move your code to instance block and it should work fine.
So when something unexpected happens in your static block, your application is expected not to continue.
So basically , all those unexpected exceptions in static block will be represented by ExceptionInIntiializerError.
You can refer to here
Related
I've a question about catching an exception in method that use another method that can throw an exception.
public void methodA(File file) {
try {
}
catch (IOException ex) {
}
}
public void methodB() {
// do something with the file
File file = new File("/example.txt");
methodA(file);
}
Do I need to create a try and catch block inside the methodB? Or it's enough to catch the exception in that case IOException inside methodA?
It depends on what you'd like to achieve.
In your code sample, methodA will handle an exception and continue a methodB execution with no interrupts. This is probably not what you'd like since there was an error reading file and it should be gracefully handled.
Most likely you'd like to bubble your exception up the execution chain and handle it in a relevant object (eg. some error handler that can output error message to an user) .
Bubble up your exception like this:
public void methodA(File file) throws CustomUserInputException {
try {
}
catch (IOException ex) {
throw new CustomUserInputException(ex, "Error opening file" + file.getPath());
}
}
and then handle it in an approptiate object like this:
public void methodB() {
// do something with the file
File file = new File("/example.txt");
try {
methodA(file);
}
catch (CustomUserInputException ex) {
showErrorToAnUser();
stopStandardProgramExecution();
}
}
No, in this case you do not need to in methodB - but you might want to, because methodA might throw other errors beside IOException.
It depends on your intention and the type of exception - if your methodA throws a checked exception methodB has to either catch it or declare that it throws that exception. If its an RuntimeException, methodB might catch it or ignore it.
In most techstacks, checked exception are rare, most think they are a failed experiment.
Lastly, whether a method needs to catch exception or not depends - can methodB conceivably handle the error? If so, catch it there - if not, let it bubble up, e.g. to a general error handler or even crash the program. nothing is more annoying than a program which catches every error and does the wrong thing.
You can't since the exception can only move up the callstack. If the program also ran methods following the exception, whats the point of even creating an exception in the first place?
Try to handle exceptions where they occour. If there is a possibility of an exception when creating a File, it should be handled where the file is created. Otherwise the overhead of making sure that incoming values are not exceptions would be way too high.
I would suggest either catching it inside methodBor passing the file name into methodA and have it create the File and catch any exceptions.
What is the point of catching and then also throwing an Exception like below? Is it bad practice to do both?
try{
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
Usually, such code is used to re-wrap exceptions, that means transforming the type of the exception. Typically, you do this when you are limited in what exceptions are allowed out of your method, but internally other types of exceptions can happen. For example:
class MyServiceImplementaiton implements MyService {
void myService() throws MyServiceException { // cannot change the throws clause here
try {
.... // Do something
} catch(IOException e) {
// re-wrap the received IOException as MyServiceException
throw new MyServiceException(e);
}
}
}
This idiom enables to keep propagating exceptions to the caller, while conforming to the throws clause in the interface and hide the details of the internals (the fact that IOExceptions can happen).
In practice, this is always better than just calling e.printStackTrace() which will actually "swallow" the error condition and let the rest of the program run as if nothing had happened. In this respect, behaviour of Eclipse is quite bad as it tends to auto-write such bad-practice constructs if the developer is not careful.
This is called rethrowing an exception, and it is a common pattern.
It allows you to change the class of the exception (such as in this case), or to add more information (also the case here, as long as that error string is meaningful).
It is often a good idea to attach the original exception:
throw new RuntimeException("cause of the problem", e);
Rethrowing as an unchecked exception (a RuntimeException) is sometimes necessary when you still want to throw an exception, but the API of your method does not allow a checked exception.
In your example, an Exception is caught and a RuntimeException is thrown, which effectively replaces a (potentially) checked exception with an unchecked exception that doesn't have to be handled by the caller, nor declared by the throwing method in a throws clause.
Some examples :
This code passes compilation :
public void SomeMethod ()
{
try {
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
}
This code doesn't pass compilation (assuming "something" may throw a checked exception) :
public void SomeMethod ()
{
//something
}
An alternative to catching the Exception and throwing an unchecked exception (i.e. RuntimeException) is to add a throws clause :
public void SomeMethod () throws Exception
{
//something
}
This is one use case of catching one type of exception and throwing another. Another use case is to catch one type of exception and throw another type of checked exception (that your method declares in its throws clause). It is sometimes done in order to group multiple exceptions that may be thrown inside a method, and only throw one type of exception to the caller of the method (which makes it easier for them to write the exception handling code, and makes sense if all those exceptions should be handled in the same manner).
I am creating a basic math parser with Java and doing this is revealing my shallow understanding of Java exception handling.
when I have this input:
String mathExpression = "(3+5";
and I subsequently call:
throw new MissingRightParenException();
the IDE forces me to surround with a try/catch like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
however, in order to force this to be a fatal exception, it looks like I have to add my own code to call System.exit(), like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
}
I am not sure I understand the syntax behind all of this, especially why I have to use a try/catch block around throwing an exception.
what is the rhyme and reason behind this?
Instead of throwing the exception, I could do this instead:
new MissingRightParenException();
instead of calling
throw new MissingRightParenException();
so I guess my question is - if this is a fatal exception, what is the best way to make it truly fatal while giving the user the best feedback?
If you want to have a checked exception that you have to catch - but not right away - then you can define throws MissingRightParenException in the signature of your methods.
class MissingRightParenException extends CalculationException {
...
}
class CalculationException extends Exception {
...
}
class MyClass {
int myMathRelatedMethod(String calculation) throws CalculationException {
...
if (somethingWrong) {
throw new MissingRightParenException("Missing right paren for left paren at location: " + location);
}
...
}
public static void main(String ... args) {
...
try {
myMathRelatedMethod(args[0]);
} catch (CalculationException e) {
// stack trace not needed maybe
System.err.println(e.getMessage());
}
...
}
}
You can also define it as the cause of a RuntimeException but that doesn't seem a good match for your current problem.
try {
...
throw new MissingRightParenException();
...
} catch (MissingRightParenException e) {
// IllegalStateException extends (IS_A) RuntimeException
throw new IllegalStateException("This should never happen", e);
}
If your MissingRightParenException class extends RuntimeException then you don't have to catch it. The message will fall through all methods where it (or it's parent classes such as Throwable, Exception and RuntimeException) is not explicitly caught. You should however not use RuntimeExceptions for input related errors.
Usually the user will get the stack trace or at least the error message, although that depends of course or the error handling further down the line. Note that even main does not have to handle exceptions. You can just specify throws Exception for the main method to let the console receive the stack traces.
So in the end: use throws in the signature of your methods instead of catching exceptions before you want to handle them.
Assuming that your exception is currently a subclass of Exception, which is a Checked Exception, you need to handle in a try catch. If you can make your exception a RunTimeException, you no longer need to do the try-catch stuffs.
what is the best way to make it truly fatal while giving the user the
best feedback?
Personally, I don't think a missing parenthesis should be a Fatal exception. The user should have the possibility to re-try.
However, if you really want to know, It is not possible with java to create a custom fatal exception as fatal exception means something went wrong on the system/jvm, not on the program itself. Still, you should change System.exit(0) to System.exit(1) or anything not equal to 0 as a program exiting with 0 as error code mean everything went right which is not the definition of an exception.
I am not sure I understand the syntax behind all of this
Basically what you do here is throw an exception so you have two choices, either catch it or re-throw it but anyway it will have to be caught somewhere. Then in the catch you simply end the program returning an error code meaning that something failed System.exit(1)
See this Difference in System. exit(0) , System.exit(-1), System.exit(1 ) in Java for a better understanding of error code.
If MissingRightParenException is a checked exception (that seems to be the case, otherwise your IDE wouldn't be "nagging") then either you have to wrap it inside a try ... catch block or declare it via a throws clause in the method definition. The latter allows you to "bubble up" the exception and catch in the caller of your method throwing the MissingRightParenException exception.
Did you think about a throws clause?
I managed to bypass the try catch block,
by nesting multiple threads.
Is therere some rule, where it is documented, when the try catch block is bypassed by Exceptions?
try{
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println("Thread");
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
System.out.println("ThreadGUI");
throw new NullPointerException();
}
});
}
};
Thread t = new Thread(r);
t.start();
} catch(NullPointerException e) {
//nothing
}
System.out.println("Ende");
Exceptions don't automatically propagate across thread boundaries. If you throw an exception in a particular thread, you can only catch it in that thread. The lexical structure of your code makes no difference in this respect.
The following are the relevant parts of the JLS:
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.
...
If no catch clause that can handle an exception can be found, then the current thread (the thread that encountered the exception) is terminated.
Your exception is thrown out in a different thread. This is why it is not caught. You might want to catch it inside tyour new thread and somehow propagate it to the main one.
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.