Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6433222

EventHandler will throw ArrayIndexOutOfBoundsException in can't find method

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 5.0
    • client-libs

      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.

            malenkov Sergey Malenkov (Inactive)
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: