10

IMPORTANT: This question only relates to Java 6 (and below).

The hierarchy here shows Java Exceptions are divided into two types: RuntimeException and [not a RuntimeException]:

Java exceptions hierarchy

Would it not have been better to divide into something like UncheckedException and CheckedException instead? For example, the following statement has quite a few checked exceptions:

try {
    transaction.commit();
} catch (SecurityException e) {
} catch (IllegalStateException e) {
} catch (RollbackException e) {
} catch (HeuristicMixedException e) {
} catch (HeuristicRollbackException e) {
} catch (SystemException e) {
}

Am only really interested in whether it succeeds or fails so would like to deal with the checked exceptions as a group but not the unchecked exceptions as it's not good practice to catch an unexpected error. So with this in mind, maybe I could do something like:

try {
    transaction.commit();
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // Throw unchecked exception
        throw e;
    }
    // Handle checked exception
    // ...
}

But this seems horribly hacky. Is there a better way?

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
  • 3
    Which version of Java are you using? (Java 7 has additional features around this.) – Jon Skeet Feb 08 '13 at 11:12
  • Oooh - didn't know that! I'm using 1.6. – Steve Chambers Feb 08 '13 at 11:13
  • Worth noting that Java exceptions are actually divided into not two but three types RuntimeException, Exceptions that are not RuntimeExceptions and Errors. – Benjamin Gruenbaum Feb 08 '13 at 11:15
  • Hmmmm not *strictly* true as an Error isn't an Exception. – Steve Chambers Feb 08 '13 at 11:16
  • 1
    Correct, I did not think about that seperation, I'm guessing a more correct thing to say would have been "Java throwables are divided into three parts" – Benjamin Gruenbaum Feb 08 '13 at 11:34
  • Alternatively it could be RuntimeException and CheckException or something like this, was also confused that RuntimeExcepions are a subclass of the checked Exception and now wondering how to catch only all checked ones, after figuring out my mistake. ;) – Stuepfnick Jun 05 '23 at 12:49

3 Answers3

12

If I understood correctly, then you are almost there. Just catch RuntimeException. That will catch RuntimeException and everything under it in the hierarchy. Then a fallthrough for Exception, and you're covered:

try {
    transaction.commit();
} catch (RuntimeException e) {
    // Throw unchecked exception
    throw e;
} catch (Exception e) {
    // Handle checked exception
    // ...
}
David Lavender
  • 8,021
  • 3
  • 35
  • 55
  • 1
    Like it. I still wonder why they didn't include a category for "NonRuntimeException" but this does the job. – Steve Chambers Feb 08 '13 at 11:20
  • 1
    Worth noting that this is not the _Java way_ (that is, it is not very _Java_ to catch very general exception types). That said I personally think this is fine and that java got exceptions wrong. – Benjamin Gruenbaum Feb 08 '13 at 11:35
5

Java 7 allows you such constructions:

try {
    transaction.commit();
} catch (SecurityException | IllegalStateException  | RollbackException | HeuristicMixedException  e ) {
   // blablabla
}

UPD: I think, that there isn't nice and convenient way for doing it in earlier versions of Java. That is why developers of Java language introduced such construction in Java 7. So, you could devise your own approaches for Java 6.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
  • OP specifically said he is using version 1.6 and not 1.7 – Benjamin Gruenbaum Feb 08 '13 at 11:13
  • 1
    Lovely, I was wondering if something like that existed! Good to know they've improved it in 7 but unfortunately I'm confined to 6. Kind of makes the question redundant though I suppose! – Steve Chambers Feb 08 '13 at 11:15
  • @BenjaminGruenbaum He said it after I posted my answer. Do you think that I should immediately delete my answer? – Andremoniy Feb 08 '13 at 11:15
  • @Andremoniy No, I think it's a good answer that will help future users, I made that comment so you'd hopefully add something about the java 1.6 case in it as well. Also, here is a good link illustrating the added functionality in 1.7 http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html – Benjamin Gruenbaum Feb 08 '13 at 11:17
  • Can't we able to have a parent class to all this exceptions – Suganthan Madhavan Pillai May 27 '16 at 12:25
-1

I gave a similar answer in another post, so yes, it is copy past:

Something that I do is to have a static method that handles all exceptions and I add the log to a JOptionPane to show it to the user, but you could write the result to a file in FileWriter wraped in a BufeeredWriter. For the main static method, to catch the Uncaught Exceptions I do:

SwingUtilities.invokeLater( new Runnable() {
    @Override
    public void run() {
        //Initializations...
    }
});


Thread.setDefaultUncaughtExceptionHandler( 
    new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException( Thread t, Throwable ex ) {
            handleExceptions( ex, true );
        }
    }
);

And as for the method:

public static void handleExceptions( Throwable ex, boolean shutDown ) {
    JOptionPane.showMessageDialog( null,
        "A CRITICAL ERROR APPENED!\n",
        "SYSTEM FAIL",
        JOptionPane.ERROR_MESSAGE );

    StringBuilder sb = new StringBuilder(ex.toString());
    for (StackTraceElement ste : ex.getStackTrace()) {
        sb.append("\n\tat ").append(ste);
    }


    while( (ex = ex.getCause()) != null ) {
        sb.append("\n");
        for (StackTraceElement ste : ex.getStackTrace()) {
            sb.append("\n\tat ").append(ste);
        }
    }

    String trace = sb.toString();

    JOptionPane.showMessageDialog( null,
        "PLEASE SEND ME THIS ERROR SO THAT I CAN FIX IT. \n\n" + trace,
        "SYSTEM FAIL",
        JOptionPane.ERROR_MESSAGE);

    if( shutDown ) {
        Runtime.getRuntime().exit( 0 );
    }
}

In you case, instead of "screaming" to the user, you could write a log like I told you before:

String trace = sb.toString();

File file = new File("mylog.txt");
FileWriter myFileWriter = null;
BufferedWriter myBufferedWriter = null;

try {
    //with FileWriter(File file, boolean append) you can writer to 
    //the end of the file
    myFileWriter = new FileWriter( file, true );
    myBufferedWriter = new BufferedWriter( myFileWriter );

    myBufferedWriter.write( trace );
}
catch ( IOException ex1 ) {
    //Do as you want. Do you want to use recursive to handle 
    //this exception? I don't advise that. Trust me...
}
finally {
    try {
        myBufferedWriter.close();
    }
    catch ( IOException ex1 ) {
        //Idem...
    }

    try {
        myFileWriter.close();
    }
    catch ( IOException ex1 ) {
        //Idem...
    }
}

I hope I have helped.

Have a nice day. :)

Saclyr Barlonium
  • 453
  • 4
  • 12