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

ArrayIndexOutOfBoundsException with SortedList

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 8u60
    • javafx
    • x86_64
    • windows_7

      FULL PRODUCT VERSION :
      java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      SortedList causes uncaught ArrayIndexOutOfBoundsException when resorting.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the code provided

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Expect it not to throw uncatchable exception
      ACTUAL -
      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -6
      at javafx.collections.transformation.SortedList.findPosition(SortedList.java:318)
      at javafx.collections.transformation.SortedList.removeFromMapping(SortedList.java:359)
      at javafx.collections.transformation.SortedList.addRemove(SortedList.java:389)
      at javafx.collections.transformation.SortedList.sourceChanged(SortedList.java:105)
      at javafx.collections.transformation.TransformationList.lambda$getListener$15(TransformationList.java:106)
      at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
      at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
      at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
      at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
      at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
      at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
      at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
      at javafx.collections.ModifiableObservableListBase.set(ModifiableObservableListBase.java:163)
      at test.collections.TestListUpdate.lambda$3(TestListUpdate.java:119)
      at com.sun.javafx.collections.MapListenerHelper$SingleChange.fireValueChangedEvent(MapListenerHelper.java:163)
      at com.sun.javafx.collections.MapListenerHelper.fireValueChangedEvent(MapListenerHelper.java:72)
      at com.sun.javafx.collections.ObservableMapWrapper.callObservers(ObservableMapWrapper.java:115)
      at com.sun.javafx.collections.ObservableMapWrapper.put(ObservableMapWrapper.java:173)
      at test.collections.TestListUpdate$Person.setAge(TestListUpdate.java:22)
      at test.collections.TestListUpdate.main(TestListUpdate.java:136)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      added 0x1e80bfe8 [bob, 0yo]
      added 0x50040f0c [john, 0yo]
      return -8; [bob, 0yo] < [john, 0yo]
      added 0x2dda6444 [joe, 0yo]
      return -8; [bob, 0yo] < [joe, 0yo]
      return 3; [john, 0yo] > [joe, 0yo]
      added 0x5e9f23b4 [ed, 0yo]
      return 5; [joe, 0yo] > [ed, 0yo]
      return -3; [bob, 0yo] < [ed, 0yo]
      added 0x4783da3f [fred, 0yo]
      return -1; [ed, 0yo] < [fred, 0yo]
      return 4; [joe, 0yo] > [fred, 0yo]
      --------------------------------------------------------
      get person @ index 3
      set age of 'ed' @ index 3 to 73
      'ed' @ 3; 'age':[73] added
      reset 'ed' @ 3
      replaced 0x5e9f23b4 [ed, 73yo] with 0x5e9f23b4 [ed, 73yo]
      return -73; [fred, 0yo] < [ed, 73yo]
      return -73; [joe, 0yo] < [ed, 73yo]
      return -73; [john, 0yo] < [ed, 73yo]
      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -6
      at javafx.collections.transformation.SortedList.findPosition(SortedList.java:318)
      at javafx.collections.transformation.SortedList.removeFromMapping(SortedList.java:359)
      at javafx.collections.transformation.SortedList.addRemove(SortedList.java:389)
      at javafx.collections.transformation.SortedList.sourceChanged(SortedList.java:105)
      at javafx.collections.transformation.TransformationList.lambda$getListener$15(TransformationList.java:106)
      at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
      at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
      at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
      at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
      at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
      at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
      at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
      at javafx.collections.ModifiableObservableListBase.set(ModifiableObservableListBase.java:163)
      at test.collections.TestListUpdate.lambda$3(TestListUpdate.java:119)
      at com.sun.javafx.collections.MapListenerHelper$SingleChange.fireValueChangedEvent(MapListenerHelper.java:163)
      at com.sun.javafx.collections.MapListenerHelper.fireValueChangedEvent(MapListenerHelper.java:72)
      at com.sun.javafx.collections.ObservableMapWrapper.callObservers(ObservableMapWrapper.java:115)
      at com.sun.javafx.collections.ObservableMapWrapper.put(ObservableMapWrapper.java:173)
      at test.collections.TestListUpdate$Person.setAge(TestListUpdate.java:22)
      at test.collections.TestListUpdate.main(TestListUpdate.java:136)

      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
      package test.collections;

      import java.util.Arrays;

      import javafx.collections.FXCollections;
      import javafx.collections.ListChangeListener;
      import javafx.collections.MapChangeListener;
      import javafx.collections.ObservableList;
      import javafx.collections.ObservableMap;

      public class TestListUpdate {
      static class Person {
      ObservableMap<String, Object> data = FXCollections.observableHashMap();

      public Person(String name) {
      setName(name);
      }

      void setName(String name) { data.put("name", name); }
      String getName() { return (String) data.get("name"); }

      void setAge(int age) { data.put("age", age); }
      int getAge() { return (int) data.getOrDefault("age", 0); }

      @Override public String toString() { return String.format("%s, %d", getName(), getAge()); }
      }

      public static void main(String[] args) {
      // create observable list of people
      ObservableList<Person> people = FXCollections.observableArrayList();

      // add listener to track changes to list (does not contribute to problem)
      people.addListener(
      (ListChangeListener<? super Object>) c -> {
      while (c.next()) {
      if (c.wasReplaced()) {
      System.out.printf(
      "replaced 0x%08x %s with 0x%08x %s\n",
      c.getRemoved().get(0).hashCode(),
      c.getRemoved(),
      c.getAddedSubList().get(0).hashCode(),
      c.getAddedSubList());
      } else if (c.wasAdded()) {
      System.out.printf(
      "added 0x%08x %s\n",
      c.getAddedSubList().get(0).hashCode(),
      c.getAddedSubList());
      } else if (c.wasRemoved()) {
      System.out.printf(
      "removed 0x%08x %s\n",
      c.getRemoved().hashCode(),
      c.getRemoved());
      }
      }
      });

      // create sorted list of people by age/name
      people.sorted(
      (p1, p2) -> {
      int equality = 0;

      if (p1.getAge() != p2.getAge()) {
      equality = p1.getAge() - p2.getAge();
      } else {
      equality = p1.getName().compareToIgnoreCase(p2.getName());
      }

      System.out.printf(
      "return %d; [%s] %s [%s]\n",
      equality,
      p1,
      equality < 0 ? "<" : equality > 0 ? ">" : "==",
      p2);

      return equality;
      });

      // add people to list
      Arrays.asList("bob", "john", "joe", "ed", "fred")
      .forEach(
      n -> {
      Person p = new Person(n);

      // add the person to the list
      people.add(p);

      // listen for change to the person
      p.data.addListener(
      (MapChangeListener<? super String, ? super Object>) c -> {
      // get the index of the person in the list
      int index = people.indexOf(p);

      if (c.wasRemoved() && c.wasAdded()) {
      System.out.printf(
      String.format(
      "'%s' @ %d; '%s' changed from [%s] to [%s]\n",
      p.getName(),
      index,
      c.getKey(),
      c.getValueRemoved(),
      c.getValueAdded()));
      } else {
      System.out.printf(
      String.format(
      "'%s' @ %d; '%s':[%s] %s\n",
      p.getName(),
      index,
      c.getKey(),
      c.wasAdded() ? c.getValueAdded() : c.getValueRemoved(),
      c.wasAdded() ? "added" : "removed"));
      }

      System.out.printf("reset '%s' @ %d\n", p.getName(), index);

      // **********************************************************************
      // SOMETHING ABOUT THE PERSON CHANGED, SO RESET THE PERSON IN THE
      // LIST TO TRIGGER AN UPDATE TO THE PERSON LIST
      // **********************************************************************
      people.set(index, p);
      });
      });

      // randomly chose a person in the list and change their age to cause an update to the
      // list of people
      while (true) {
      int index = (int) ((people.size() - 1) * Math.random());

      System.out.println("--------------------------------------------------------");
      System.out.printf("get person @ index %d\n", index);

      Person p = people.get(index);
      int age = (int) (Math.random() * 100);

      System.out.printf("set age of '%s' @ index %d to %d\n", p.getName(), index, age);

      p.setAge(age);

      // **********************************************************************
      // an exception in SortList will randomly occur in this loop
      // **********************************************************************
      }
      }
      }

      ---------- END SOURCE ----------

            vadim Vadim Pakhnushev
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: