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

ArrayBlockingQueue: Attempt to invoke virtual method 'void java.util.concurrent.locks.ReentrantLock.lock()' on a null object reference

    Details

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_121"
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Android OS' across the board.

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      This happens on any Android device at complete random.

      A DESCRIPTION OF THE PROBLEM :
      Exception: java.lang.NullPointerException Attempt to invoke virtual method 'void java.util.concurrent.locks.ReentrantLock.lock()' on a null object reference

      Any call to lock.lock() is in jeopardy of crashing on a null pointer exception: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/ArrayBlockingQueue.java

      I have seen this crash in size() add() remove() offer(), all pointing the same line of code: lock.lock()

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      This issue is very elusive. We have roughly 5 million calls to some sort of ArrayBlockingQueue API every day across hundreds of thousands of Android devices. The crash is seen by a very small subset of users, but they hit it almost every single time they interact with the queue. My data has not pointed to any specific OS or phone. I do not have an exact, 100% reproducible case. Here is what I do know:
      - The crash is not specific to OS versions
      - The crash is not specific to certain phone brands only
      - I am simply making the same calls I do the millions of other times (.add, .size, .remove, etc.)
      - I have not tried my own custom automated solution to stress test this queue or anything like that

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The ArrayBlockingQueue successfully adds an item, removes an items, gets the size, etc.
      ACTUAL -
      The user crashes and has to restart the application.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Fatal Exception: java.lang.NullPointerException
      Attempt to invoke virtual method 'void java.util.concurrent.locks.ReentrantLock.lock()' on a null object reference:
      java.util.concurrent.ArrayBlockingQueue.size (ArrayBlockingQueue.java:415)
      com.***.android.persistentqueue.PersistentQueue.size (PersistentQueue.java:101)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.addUrlAndProcess (DeepLinkingPersistentQueueService.java:137)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.onHandleIntent (DeepLinkingPersistentQueueService.java:95)
      android.app.IntentService$ServiceHandler.handleMessage (IntentService.java:65)
      android.os.Handler.dispatchMessage (Handler.java:102)
      android.os.Looper.loop (Looper.java:145)
      android.os.HandlerThread.run (HandlerThread.java:61)

      Fatal Exception: java.lang.NullPointerException
      Attempt to invoke virtual method 'void java.util.concurrent.locks.ReentrantLock.lock()' on a null object reference:
      java.util.concurrent.ArrayBlockingQueue.offer (ArrayBlockingQueue.java:297)
      java.util.AbstractQueue.add (AbstractQueue.java:66)
      java.util.concurrent.ArrayBlockingQueue.add (ArrayBlockingQueue.java:282)
      com.***.android.persistentqueue.PersistentQueue.add (PersistentQueue.java:41)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.addUrlAndProcess (DeepLinkingPersistentQueueService.java:122)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.onHandleIntent (DeepLinkingPersistentQueueService.java:95)
      android.app.IntentService$ServiceHandler.handleMessage (IntentService.java:65)
      android.os.Handler.dispatchMessage (Handler.java:110)
      android.os.Looper.loop (Looper.java:193)
      android.os.HandlerThread.run (HandlerThread.java:61)


      java.util.concurrent.ArrayBlockingQueue.remove (ArrayBlockingQueue.java:467)
      com.amazon.sellermobile.android.persistentqueue.PersistentQueue.remove (PersistentQueue.java:70)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.removeEventFromQueue (DeepLinkingPersistentQueueService.java:357)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.processEvent (DeepLinkingPersistentQueueService.java:348)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService.access$300 (DeepLinkingPersistentQueueService.java:40)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService$1.onRequestSuccess (DeepLinkingPersistentQueueService.java:226)
      com.***.android.deeplinking.DeepLinkingPersistentQueueService$1.onRequestSuccess (DeepLinkingPersistentQueueService.java:164)
      com.***.android.util.asynctasks.JsonRequestTask.onPostExecute (JsonRequestTask.java:373)
      com.***.android.util.asynctasks.JsonRequestTask.onPostExecute (JsonRequestTask.java:84)
      android.os.AsyncTask.finish (AsyncTask.java:632)
      android.os.AsyncTask.access$600 (AsyncTask.java:177)
      android.os.AsyncTask$InternalHandler.handleMessage (AsyncTask.java:645)
      android.os.Handler.dispatchMessage (Handler.java:102)
      android.os.Looper.loop (Looper.java:145)
      android.app.ActivityThread.main (ActivityThread.java:5951)
      java.lang.reflect.Method.invoke (Method.java)
      java.lang.reflect.Method.invoke (Method.java:372)
      com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1400)
      com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1195)

      REPRODUCIBILITY :
      This bug can be reproduced occasionally.

      ---------- BEGIN SOURCE ----------
           private ArrayBlockingQueue<E> queue = new ArrayBlockingQueue<E>(maxQueueSize)

           public boolean add(E e) {
              boolean retVal;
              synchronized (this) {
                  retVal = this.queue.add(e); // <-- this line triggers the crash
                  this.saveQueue(); // flush queue to storage
              }
              return retVal;
          }

          public void clear() {
              synchronized (this) {
                  this.queue.clear(); // <-- this line triggers the crash
                  saveQueue(); // flush queue to storage
              }
          }

          public boolean remove(E e) {
              boolean retVal;
              synchronized (this) {
                  retVal = this.queue.remove(e); // <-- this line triggers the crash
                  this.saveQueue(); // flush queue to storage
              }
              return retVal;
          }

          public int size() {
              return this.queue.size(); // <-- this line triggers the crash
          }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Silly try catch blocks around the offending calls into the APIs to not crash the users app. Terrible workaround.

        Attachments

          Activity

            People

            • Assignee:
              psonal Pallavi Sonal
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: