2

Problem

A field member is suddenly becoming a null value during android runtime on Nexus 5x devices

Steps already taken

  1. I have verified there are no other writes to that field in my codebase, reflection or otherwise
  2. I have reproduced it multiple times, but only on the Nexus 5X device. Have been unsuccessful reproducing it on other devices
  3. I have identified an odd behavior on the Nexus 5X device independent of my app.

Simplified class example:

public class TestA
{
    // While not final, could have been final as no writes other than in the constructor
    private Object impossibleToBeNull;

    public TestA()
    {
        impossibleToBeNull = new Object();
    }

    public void method1()
    {
        impossibleToBeNull.toString(); // Null pointer occurs here
    }
}

Description

Somehow, during the runtime of my Android App, a NullPointerException is thrown in my actual equivalent of "method1" from the simplified class example above. I cannot identify any valid situation in which this variable would be null, as it is constructed in the TestA constructor, and if it were to fail in its construction, there would not be a TestA instance to call "method1" on.

The only additional information I have is that the occurrences happen on dispatchTouchEvent, and specifically only on a Nexus 5x device(Have been unable to reproduce it on other devices).

Interesting potentially unrelated Nexus 5X quirk/bug

There appears to be a strange behavior on the Nexus 5x where if you bring your two fingers together in a single gesture and hold them together in just the right fashion, thousands of touch inputs events go off. This occurs both inside apps and on the home screen, and is not limited to any one app. This may be related, or it may just be doing enough input actions for the reproduction.

Potential Causes

  1. Serialization (Variable could be deserialized to null) - The class is never serialized
  2. Reflection by my codebase - I do not use reflection anywhere
  3. Reflection by something external???(i.e. android?) Not sure if anything does that
  4. Memory corruption - This seems like it would be very difficult to do in a Java app
  5. My code sets it to null - I only access that field member in the constructor
  6. Constructor has not finished yet when method called - The constructor literally just contains the setter for the field, nothing else. Method is called externally
  7. Android bug - Incredibly unlikely, but cannot eliminate entirely.
  8. ?????
Dan
  • 858
  • 7
  • 18
  • 1
    Does the problem occur provided the field is declared `final`? – yegodm Aug 31 '17 at 16:00
  • Have not been able to verify that just yet, that is the step I am currently taking, however I do not see how that should make a difference as final or not, there is still only a single write. – Dan Aug 31 '17 at 16:03
  • 1
    However, Java memory model makes it perfectly possible that another thead may see non-final field as `null`. – yegodm Aug 31 '17 at 16:34
  • @yegodm Are you suggesting that another thread constructed the "TestA" object, and the running thread could see the "TestA" instance but then the internal field was not visible? – Dan Aug 31 '17 at 16:40
  • 1
    Yes, it might happen that a write made by the instantiating thread is not visible by a reading thread. For example, the write might still be local to the CPU cache, and not yet published to the main memory, where other threads might see it. – yegodm Aug 31 '17 at 17:07
  • Is the class you're talking about an Activity or a Fragment? – algrid Aug 31 '17 at 17:17

1 Answers1

0

It seems that @yegodm was correct in his comment on my post. According to Oracle docs Because the reference to my "TestA" object is set from another thread, the nonfinal member might not yet be published to the main memory. Their example 17.5-1 shows this nicely.

Dan
  • 858
  • 7
  • 18