Duplicate :
|
FULL PRODUCT VERSION : java version "1.5.0_06" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05) Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode) ADDITIONAL OS VERSION INFORMATION : Linux rpc268 2.6.15-gentoo-r1 #1 SMP Tue Mar 7 16:41:59 GMT 2006 i686 Intel(R) Pentium(R) D CPU 3.20GHz GenuineIntel GNU/Linux A DESCRIPTION OF THE PROBLEM : This is also described in bug 4511992, but that is falsely closed and referred to a not-so-very-relevant bug about the documentation. There is a bug in the CODE of EventHandler.java If calling EventHandler.create(SomeListener.class, this, "wrong") and invoking public static <T> T create(Class<T> listenerInterface, Object target, String action) then both eventPropertyName and listenerMethodName will be set to null, and when the EventHandler is invoked: if (eventPropertyName == null) { // Nullary method. newArgs = new Object[]{}; argTypes = new Class[]{}; if (targetMethod == null) { targetMethod = ReflectionUtils.getMethod(target.getClass(), action, argTypes); } if (targetMethod == null) { targetMethod = ReflectionUtils.getMethod(target.getClass(), "set" + NameGenerator.capitalize(action), argTypes); } which should throw a runtime error if "getWrong" or "setWrong" does not exist: if (targetMethod == null) { throw new RuntimeException("No method called: " + action + " on class " + target.getClass() + " with argument " + argTypes[0]); } .. but obviously this won't work when argTypes is an empty array. And so an ArrayIndexOfBoundsException is thrown instead. Suggested fix: Avoid using argTypes[0] in the exception throwing. STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Compile swing-code given with 1.5, run with 1.5 EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Expected RunTimeException to help explain somewhat that "nonExisting" was not a very good argument for EventHandler.create(), ie a traceback with something like: Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: No method called nonExisting on class EventCrasher. ACTUAL - The internal "raise exception" code of EventHandler.invokeInternal has a bug where it reads from an empty array: Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 at java.beans.EventHandler.invokeInternal(EventHandler.java:379) at java.beans.EventHandler.access$000(EventHandler.java:205) at java.beans.EventHandler$1.run(EventHandler.java:338) at java.security.AccessController.doPrivileged(Native Method) at java.beans.EventHandler.invoke(EventHandler.java:336) at $Proxy0.focusGained(Unknown Source) at java.awt.AWTEventMulticaster.focusGained(AWTEventMulticaster.java:162) at java.awt.Component.processFocusEvent(Component.java:5377) at java.awt.Component.processEvent(Component.java:5244) at java.awt.Container.processEvent(Container.java:1966) at java.awt.Component.dispatchEventImpl(Component.java:3955) at java.awt.Container.dispatchEventImpl(Container.java:2024) at java.awt.Component.dispatchEvent(Component.java:3803) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1810) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:831) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:480) at java.awt.Component.dispatchEventImpl(Component.java:3841) at java.awt.Container.dispatchEventImpl(Container.java:2024) at java.awt.Component.dispatchEvent(Component.java:3803) at sun.awt.X11.XWindow$1.run(XWindow.java:331) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:461) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149) at java.awt.EventDispatchThread.run(EventDispatchThread.java:110) REPRODUCIBILITY : This bug can be reproduced occasionally. ---------- BEGIN SOURCE ---------- import java.awt.event.FocusListener; import java.beans.EventHandler; import javax.swing.JFrame; import javax.swing.JTextField; public class EventCrasher extends JFrame { public EventCrasher() { super(); JTextField field = new JTextField("Hello", 25); this.add(field); field.addFocusListener((FocusListener) EventHandler.create( FocusListener.class, this, "nonExisting")); } public static void main(String[] args) { EventCrasher a = new EventCrasher(); a.setVisible(true); a.toFront(); } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : (For the user): Use a method name that exists (For Sun): Don't include argTypes[0] when throwing exceptions. Include unittests that try to raise the expected exceptions.