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

(coll) PriorityQueue.poll() throws NullPointerException

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P4
    • None
    • 6
    • core-libs

    Description

      FULL PRODUCT VERSION :
      java version "1.6.0-rc"
      Java(TM) SE Runtime Environment (build 1.6.0-rc-b104)
      Java HotSpot(TM) Server VM (build 1.6.0-rc-b104, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Nothing special

      A DESCRIPTION OF THE PROBLEM :
      Invoking poll() on a PriorityQueue<Foo> occasionally throws a NullPointerException. These either take this form:

      java.lang.NullPointerException
              at java.util.PriorityQueue.siftDownComparable(PriorityQueue.java:627)
              at java.util.PriorityQueue.siftDown(PriorityQueue.java:614)
              at java.util.PriorityQueue.poll(PriorityQueue.java:523)
              at com.sourceforge.sphaera.SThread.run(SThread.java:158)

      or come bubbling up from Foo.compareTo() via siftDownComparable(). In the latter case, with a particular choice of Foo, it's been observed happening in a way that cannot be the result of anything except compareTo(null) being called, because the only thing the comparator does is compare some final fields of reference type in the receiver and the argument, and never dereferences anything except the argument.

      This seems to indicate that nulls are getting into the queue somehow, but I've confirmed this occurring where the only inserts into the queue take the form of

      Foo x = new Foo(args);
      synchronized (queue) { queue.add(x); }

      It doesn't seem possible for x to be null here. (Note also that access to the queue is being synchronized. This doesn't seem to be a concurrency problem, as all accesses being synchronized doesn't prevent it, nor does only having one thread active.)

      The queue seems to be malfunctioning, generating nulls internally. Since a procedure poll() and catch NPE, followed by poll(), succeeds, it seems that the nulls disappear when the NPE is generated.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      There's no strict recipe to reproduce it that I am aware of. Randomly generating instances of:

      class Foo implements Comparable<Foo> {
      public final String name;
      public final int priority;
      public Foo (String n, int p) { name = n; priority = p; }
      public int compareTo (Foo f) { return (p < f.p)?1:((p == f.p)?0:-1); }
      public boolean equals (Object o) {
      return this == o || (o != null && o instanceof Foo && o.name.equals(name);
      }
      public int hashCode () { return name.hashCode(); }
      }

      Note that the above compareTo is inconsistent with equals, which may be necessary to trigger the bug. Randomly generate and add() Foos to a PriorityQueue and intermittently poll the queue until an NPE is thrown. It may be necessary to invoke size() and isEmpty() from time to time on the queue as well. It is not necessary to invoke remove() or anything else.

      The actual in-situ failure is happening in a scheduler with a job class resembling Foo (all fields final, inconsistent with equals; the job class objects are also dropped into hashmaps where, regardless of priority, they need to compare equal by name only.)

      One thread generates job objects and adds them to the queue; access is synchronized and it's emphatically not adding nulls. The other polls the queue from time to time and invariably dies after a short time with this NPE, but if restarted whenever it dies, the app actually works as designed despite the NPE(!).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      As long as concurrent access is synchronized:
        PriorityQueue should not call compareTo() on an element with a null argument.
        PriorityQueue should not throw NPE, at least if no nulls are ever inserted into the queue.
      ACTUAL -
      Even when concurrent access is synchronized:
        PriorityQueue calls compareTo() on elements with null arguments on rare occasions.
        PriorityQueue throws NPEs from internal code from time to time, even when no nulls are ever inserted.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.NullPointerException
              at java.util.PriorityQueue.siftDownComparable(PriorityQueue.java:627)
              at java.util.PriorityQueue.siftDown(PriorityQueue.java:614)
              at java.util.PriorityQueue.poll(PriorityQueue.java:523)
              at com.sourceforge.sphaera.SThread.run(SThread.java:158)

      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
      class Foo implements Comparable<Foo> {
      public final String name;
      public final int priority;
      public Foo (String n, int p) { name = n; priority = p; }
      public int compareTo (Foo f) { return (p < f.p)?1:((p == f.p)?0:-1); }
      public boolean equals (Object o) {
      return this == o || (o != null && o instanceof Foo && o.name.equals(name);
      }
      public int hashCode () { return name.hashCode(); }
      }

      Make these randomly and insert them into a PriorityQueue<Foo> in one thread while polling the queue every few hundred msec in another. Synchronize on the queue in both threads when accessing the queue.
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Curiously, trapping and ignoring the NPEs and repolling the queue until poll() returns normally seems to suffice. It doesn't loop forever generating and catching exceptions, nor does any other misbehavior appear to happen.

      Attachments

        Activity

          People

            martin Martin Buchholz
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: