Checked exceptions are painful. I could write a long article about it, but there are more than enough good blogs describing this problem.
My favorite article is written by Rod Waldhoff.

From my point of view the existence of the InvocationTargetException clearly shows the problem.
Imagine you call a method which throws an exception, you properly catches it
and then you decide to rewrite the code and call the same method via refection.
After that you have to catch the same exception in quite a different manner: 

public class Test {

    public static void main(String[] args) {
        PrinterJob job = PrinterJob.getPrinterJob();
        // Call it in the usual way
        try {
            // this throws checked PrinterException
        } catch (PrinterException e) {
            // handle the printer exception

        // Call the same method via reflection

        try {
            // this throws InvocationTargetException instead
        } catch (IllegalAccessException e) {
        catch (InvocationTargetException e) {
            if(e.getCause() instanceof PrinterException) {
                // handle the printer exception;
                // a little bit more complicated than it used to be

    static Method getPrintMethod() {
        try {
            return Class.forName("PrinterJob").getDeclaredMethod("print");
        } catch (Exception e) {
        return null;
I would love it if Java doesn't require me to catch the InvocationTargetException and let me work with the PrinterException the same way.

Let me give you some examples that illustrate what kind of mess it brings to the Swing code base.
Fortunately there are not many checked exceptions used in Swing code, but when you implement printing you can't avoid PrinterException and PrinterAbortException.
Since printing must be done in the background to not block the GUI,
we have to properly re-throw the exceptions back to the Event Dispatching Thread thread.

So in the implementation of the JTable.print() method you can find the following construction: 

       // this runnable will be used to do the printing
        // (and save any throwables) on another thread
        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    // do the printing
                } catch (Throwable t) {
                    // save any Throwable to be rethrown
                    synchronized(lock) {
                        printError = t;
                } finally {
                    // we're finished - hide the dialog
and then we have to understand what kind of exception was thrown and how we can re-throw it back: 

       // check the type of error and handle it
        if (pe != null) {
            // a subclass of PrinterException meaning the job was aborted,
            // in this case, by the user
            if (pe instanceof PrinterAbortException) {
                return false;
            } else if (pe instanceof PrinterException) {
                throw (PrinterException)pe;
            } else if (pe instanceof RuntimeException) {
                throw (RuntimeException)pe;
            } else if (pe instanceof Error) {
                throw (Error)pe;

            // can not happen
            throw new AssertionError(pe);
This boilerplate code can't be avoided, you can find the same pattern in the implementation of JTable.print().
If the methods that are called on the background thread threw another checked exceptions, we would have to add another instanceof checks there.
More checked exceptions - more lines of code.

If there were no checked exceptions in java, that kind of code would be unnecessary,
we could freely re-throw any exception no matter what their type is.
I would definitely remove the checked exceptions from Java.

This was an entry from the Swing in a better world series