Wednesday, August 12, 2015

An interesting JDK6 bug about EventDispatchThread

An interesting JDK6 bug about EventDispatchThread

0. Background
Need add read only access control for legacy Java Swing modules.

1. What's the issue
To avoid the changes scattered in many places, ReadonlyException is defined and DefaultUncaughtExceptionHandler is set in one place. It looks good
except for the modal popup dialog. There's a message on console:
Exception occurred during event dispatching:...

2. What's the cause
The message comes from EventDispatchThread.java:
            if (isModal) {
                System.err.println(
                    "Exception occurred during event dispatching:");
                e.printStackTrace();
            } else if (e instanceof RuntimeException) {
                throw (RuntimeException)e;
            } else if (e instanceof Error) {
                throw (Error)e;
            }
    if it's a modal dialog, the exception will be captured by EDT, the problem is that EDT does not pass it to UncaughtExceptionHandler like JDK7 or JDK8:
getUncaughtExceptionHandler().uncaughtException(this, e);

3. How to fix
By debugging/tracking the JDK source code, we can set property "sun.awt.exception.handler" but even after I set the property, issue is still there.
Checking the EventDispatchTread.java source again, and there's a block:
       try {
                ClassLoader cl = Thread.currentThread().getContextClassLoader();
                Class c = Class.forName(handlerClassName, true, cl);
                m = c.getMethod("handle", new Class[] { Throwable.class });
                h = c.newInstance();
            } catch (Throwable x) {
                handlerClassName = NO_HANDLER; /* Do not try this again */
                return false;
            }
It means that it will invoke the handler's handle method, and the handler must have a non-parameter construtctor. The worst thing is that it does not print any
error message when the exception happens. Until I checked here, I realized I need add a non-parameter construtctor to the handler.

4. More about the bug:
http://bugs.java.com/view_bug.do?bug_id=6727884
I verified it worked perfect on JDK8 without the workaround and it failed to show the popup message on JDK6 without the workaround.

How to debug JDK source code:
1. Unzip src.zip and create a java project in Eclipse, set the source to the unzipped src folder
2. If there's compilor error (...is not accessible due to restriction...), remove JRE library and add them back to let Eclipse use the right class first
3. Export the jar file and put it into %JDK%\jre\lib\endorsed. Create endorsed folder if it's not there. We don't have permission to operate on the default
JDK home, so need to set JDK home to other place.

No comments:

Post a Comment