Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed application crash issue due to NullPointerException on exit #206

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

hetul-patel
Copy link

There is an issue when application is closed. tlModel is set to null in onDestroy() but InferenceThread still calls tlModel.predict method without checking a null.

Prediction[] predictions = tlModel.predict(rgbImage);

java.lang.NullPointerException is thrown at this line. Solved it using try-catch.

@googlebot googlebot added the cla: yes CLA has been signed label Apr 26, 2020
try {
predictions = tlModel.predict(rgbImage, modelImageSize, modelImageSize);
}
catch (Exception e){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Could you specifically catch NullPointerException instead? It would be bad to catch all exceptions and ignore them in case something else happens.
  2. Also, please add a comment explaining why the NullPointerException can be thrown and why we are ignoring it.

Thanks for your contribution!

@hetul-patel
Copy link
Author

@yyoon Thanks for reviewing my PR.

First I would like to answer your second question.

  1. Also, please add a comment explaining why the NullPointerException can be thrown and why we are ignoring it.

As you can see here, in the OnDestroy() method, tlModel is set to a null.

  public void onDestroy() {
    super.onDestroy();
    tlModel.close();
    tlModel = null; // <== tlModel is now a null reference
    Log.d("TFL","onDestroy() completed");
  }

For some reason(I am searching) imageAnalysis use-case is not being unbounded on application exit after onDestroy is completed. As shown below, eventually a call to tfmodel.predict method is made inside inferenceAnalyzer even after tfModel is set to a null and throws a NullPointerExecption.

private final ImageAnalysis.Analyzer inferenceAnalyzer =
          (imageProxy, rotationDegrees) -> {
              ...

              Log.d("TFL","Incoming req for predict");
              Prediction[] predictions = tlModel.predict(rgbImage);

              ...
}

The exact exception thrown is this,

java.lang.NullPointerException: Attempt to invoke virtual method 'org.tensorflow.lite.examples.transfer.api.TransferLearningModel$Prediction[] org.tensorflow.lite.examples.transfer.TransferLearningModelWrapper.predict(float[])' on a null object reference
        at org.tensorflow.lite.examples.transfer.CameraFragment.lambda$new$2$CameraFragment(CameraFragment.java:180)
        at org.tensorflow.lite.examples.transfer.-$$Lambda$CameraFragment$o2DkVL-ukwqtN87dNJz2_ON_zV8.analyze(Unknown Source:2)
        at androidx.camera.core.ImageAnalysisNonBlockingCallback$1.run(ImageAnalysisNonBlockingCallback.java:150)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.os.HandlerThread.run(HandlerThread.java:65)

I have logged the sequence of method calls as show below. You can see that last request for prediction is after completion of onDestroy() which is the reason for NullPointerException.

2020-04-27 19:45:57.904 5247-5284/org.tensorflow.lite.examples.transfer D/TFL: Incoming req for predict
2020-04-27 19:45:58.219 5247-5284/org.tensorflow.lite.examples.transfer D/TFL: Incoming req for predict
2020-04-27 19:45:58.534 5247-5284/org.tensorflow.lite.examples.transfer D/TFL: Incoming req for predict
2020-04-27 19:45:58.855 5247-5284/org.tensorflow.lite.examples.transfer D/TFL: Incoming req for predict
2020-04-27 19:45:59.146 5247-5247/org.tensorflow.lite.examples.transfer D/TFL: onDestroy() completed
2020-04-27 19:45:59.227 5247-5284/org.tensorflow.lite.examples.transfer D/TFL: Incoming req for predict

Now coming to the first question.

Could you specifically catch NullPointerException instead? It would be bad to catch all exceptions and ignore them in case something else happens.

Yes sure. I can handle NullPointerException specifically and it solves the app crash. But the primary reason for imageAnalysis use-case not getting unbound is still unknown.

@jdduke
Copy link
Member

jdduke commented Apr 27, 2020

Catching a NullPointerException is probably not what we want, we should either add a proper lock for inference or do the closing on the worker thread rather than the UI thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes CLA has been signed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants