-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
5.0
-
x86
-
linux
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.
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.
- duplicates
-
JDK-6204552 EventHandler documentation and exception handling problems
-
- Resolved
-