React-native-code-push: java.lang.NullPointerException: Attempt to get length of null array on some Huawei devices

Created on 22 Jan 2019  Â·  24Comments  Â·  Source: microsoft/react-native-code-push

Steps to Reproduce

1.crash log shows this error

Expected Behavior

no crash

Actual Behavior

crashed, here's the log:

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tota123.fatboy/com.tota123.fatboy.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3300)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3484)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2123)
    at android.os.Handler.dispatchMessage(Handler.java:109)
    at android.os.Looper.loop(Looper.java:207)
    at android.app.ActivityThread.main(ActivityThread.java:7470)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
    at com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently(FileUtils.java:75)
    at com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently(FileUtils.java:77)
    at com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently(FileUtils.java:77)
    at com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently(FileUtils.java:77)
    at com.microsoft.codepush.react.FileUtils.deleteDirectoryAtPath(FileUtils.java:64)
    at com.microsoft.codepush.react.CodePushUpdateManager.clearUpdates(CodePushUpdateManager.java:332)
    at com.microsoft.codepush.react.CodePush.clearUpdates(CodePush.java:264)
    at com.microsoft.codepush.react.CodePush.getJSBundleFileInternal(CodePush.java:175)
    at com.microsoft.codepush.react.CodePush.getJSBundleFile(CodePush.java:140)
    at com.microsoft.codepush.react.CodePush.getJSBundleFile(CodePush.java:132)
    at com.tota123.fatboy.MainApplication$1.getJSBundleFile(MainApplication.java:58)
    at com.facebook.react.ReactNativeHost.createReactInstanceManager(ReactNativeHost.java:78)
    at com.facebook.react.ReactNativeHost.getReactInstanceManager(ReactNativeHost.java:41)
    at com.facebook.react.ReactActivityDelegate.loadApp(ReactActivityDelegate.java:111)
    at com.facebook.react.ReactActivityDelegate.onCreate(ReactActivityDelegate.java:100)
    at com.facebook.react.ReactActivity.onCreate(ReactActivity.java:54)
    at com.tota123.fatboy.MainActivity.onCreate(MainActivity.java:84)
    at android.app.Activity.performCreate(Activity.java:7436)
    at android.app.Activity.performCreate(Activity.java:7426)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3279)
    ... 11 more

Environment

react-native-code-push version:4.0.0-beta
react-native version:0.46.0 (I know it's so old, we're trying updating)
iOS/Android/Windows version: android
Does this reproduce on a debug build or release build? release
Does this reproduce on a simulator, or only on a physical device? physical device

Other Info

Actually there is a similar issue here #1458
which is not solved but closed.
This happens on a HuaWei Mate20 phone.
It is occasionally happened and I got no such a cellphone, so I cann't reproduct it.
According to the log above, it seems that the deleteFileOrFolderSilently should be responsible for the crash.
https://github.com/Microsoft/react-native-code-push/blob/3144c916018fab077231e88d8718ad3a1cb0a7d8/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java#L74-L75

It seems that files is null? According to file.listFiles doc, this func should return An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.
So, an I/O error occurs?

android known issue wontfix

Most helpful comment

diff --git a/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java b/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
index 29d52ec..cb6926f 100644
--- a/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
+++ b/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
@@ -22,7 +22,11 @@ public class FileUtils {
             destDir.mkdir();
         }

-        for (File sourceFile : sourceDir.listFiles()) {
+        File[] files = sourceDir.listFiles();
+        if (files == null) {
+            return;
+        }
+        for (File sourceFile : files) {
             if (sourceFile.isDirectory()) {
                 copyDirectoryContents(
                         CodePushUtils.appendPathComponent(sourceDirectoryPath, sourceFile.getName()),
@@ -72,6 +76,9 @@ public class FileUtils {
     public static void deleteFileOrFolderSilently(File file) {
         if (file.isDirectory()) {
             File[] files = file.listFiles();
+            if (files == null) {
+                return;
+            }
             for (File fileEntry : files) {
                 if (fileEntry.isDirectory()) {
                     deleteFileOrFolderSilently(fileEntry);

Is the patch I'm applying, will feedback how it goes

All 24 comments

Hi @coolguy001tv,
Thanks for reporting!

Did it occasionally happen on your device (not Huawei Mate20)? Did I understand you correctly?

I just see it on some logs from server. It shows me there is a crash. I don't own this device.
So I just know it happened. Yet I think it's occasionally happened.
I don't know if I make myself clear.

Thanks, I understand now. I think this question might be related to app permissions and it's very strange, these Huawei devices may have an unusual memory configuration, but we can't test it without the actual device, so we can only assume the reasons.

Thanks for the reply. I'll try to add the permission.
Besides, I think the code here should have an if-not-null-test between line 74 & 75.
https://github.com/Microsoft/react-native-code-push/blob/3144c916018fab077231e88d8718ad3a1cb0a7d8/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java#L74-L75

@yuri-kulikov
Hi~ When I have my colleague checked our app's uses-permission ( I am not familar with Android) , and the android.permission.READ_EXTERNAL_STORAGE is in the list. It can't be the read permission.
Besides, our logs are created each time when app crashes. So if there is a read/write permission, the log can't be created and can't be uploaded to our server. But in fact we see the log in our server.

Hey @coolguy001tv,
Sorry for the delay!

Besides, I think the code here should have an if-not-null-test between line 74 & 75.

I think you're right!

However, it still won't solve the issue completely. These specific devices won't be crashed, but still won't be able to update via CodePush. And it's weird that file.isDirectory() returns true before the crash. We will try to investigate the issue in more detail.

Thanks. If I get more info, I shall comment it here.
I think I shall have left this issue open for now, at least until the if-not-null-test coded.

Same problem here:

Android, Huawei Mate 20 Pro Dual SIM (LYA-L29), Android 9, free disk space: 115924271104, free memory: 400024576.
We just released a new version of the app couple days ago, and there isn't any code-push patch for this version yet. This is first time it occurs.

```java.lang.RuntimeException Unable to start activity ComponentInfo{xxx.xxx.xxxx/xxx.xxx.xxx.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
ActivityThread.java:3300 android.app.ActivityThread.performLaunchActivity
ActivityThread.java:3484 android.app.ActivityThread.handleLaunchActivity
LaunchActivityItem.java:86 android.app.servertransaction.LaunchActivityItem.execute
TransactionExecutor.java:108 android.app.servertransaction.TransactionExecutor.executeCallbacks
TransactionExecutor.java:68 android.app.servertransaction.TransactionExecutor.execute
ActivityThread.java:2123 android.app.ActivityThread$H.handleMessage
Handler.java:109 android.os.Handler.dispatchMessage
Looper.java:207 android.os.Looper.loop
ActivityThread.java:7470 android.app.ActivityThread.main
Method.java:-2 java.lang.reflect.Method.invoke
RuntimeInit.java:524 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run
ZygoteInit.java:958 com.android.internal.os.ZygoteInit.main

Caused by: java.lang.NullPointerException Attempt to get length of null array
FileUtils.java:75 com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently
FileUtils.java:77 com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently
FileUtils.java:77 com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently
FileUtils.java:77 com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently
FileUtils.java:64 com.microsoft.codepush.react.FileUtils.deleteDirectoryAtPath
CodePushUpdateManager.java:367 com.microsoft.codepush.react.CodePushUpdateManager.clearUpdates
CodePush.java:359 com.microsoft.codepush.react.CodePush.clearUpdates
CodePush.java:241 com.microsoft.codepush.react.CodePush.getJSBundleFileInternal
CodePush.java:209 com.microsoft.codepush.react.CodePush.getJSBundleFile
CodePush.java:201 com.microsoft.codepush.react.CodePush.getJSBundleFile
MainApplication.java:88 xxx.xxx.xxx.MainApplication$1.getJSBundleFile
ReactNativeHost.java:82 com.facebook.react.ReactNativeHost.createReactInstanceManager
ReactNativeHost.java:41 com.facebook.react.ReactNativeHost.getReactInstanceManager
ReactActivityDelegate.java:86 com.facebook.react.ReactActivityDelegate.loadApp
ReactActivityDelegate.java:75 com.facebook.react.ReactActivityDelegate.onCreate
ReactActivity.java:52 com.facebook.react.ReactActivity.onCreate
MainActivity.java:20 xxx.xxx.xxx.MainActivity.onCreate
Activity.java:7436 android.app.Activity.performCreate
Activity.java:7426 android.app.Activity.performCreate
Instrumentation.java:1286 android.app.Instrumentation.callActivityOnCreate
ActivityThread.java:3279 android.app.ActivityThread.performLaunchActivity
ActivityThread.java:3484 android.app.ActivityThread.handleLaunchActivity
LaunchActivityItem.java:86 android.app.servertransaction.LaunchActivityItem.execute
TransactionExecutor.java:108 android.app.servertransaction.TransactionExecutor.executeCallbacks
TransactionExecutor.java:68 android.app.servertransaction.TransactionExecutor.execute
ActivityThread.java:2123 android.app.ActivityThread$H.handleMessage
Handler.java:109 android.os.Handler.dispatchMessage
Looper.java:207 android.os.Looper.loop
ActivityThread.java:7470 android.app.ActivityThread.main
Method.java:-2 java.lang.reflect.Method.invoke
RuntimeInit.java:524 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run
ZygoteInit.java:958 com.android.internal.os.ZygoteInit.main
```

@pawlowskim After I modified the code with an if-not-null-test like discussed above(fork this repo and then modify) , it seems that no devices crash with this error any more. U may try this if the official still faces this.

I will give it a try when it happens again. Thanks @coolguy001tv
BTW. We are using RN: 0.59.10 and code-push: 5.6.0 (both pretty up to date)

@pawlowskim Good luck to you. Besides, we've already updated rn with 0.58.1.

@pawlowskim did the fix @coolguy001tv suggest work for you?

@henrymoulton Not occurred again yet.

Sounds good, rather than forking I've used patch-package, @coolguy001tv was this the patch you recommend?

diff --git a/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java b/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
index 29d52ec..b57db9b 100644
--- a/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
+++ b/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
@@ -72,11 +72,13 @@ public class FileUtils {
     public static void deleteFileOrFolderSilently(File file) {
         if (file.isDirectory()) {
             File[] files = file.listFiles();
-            for (File fileEntry : files) {
-                if (fileEntry.isDirectory()) {
-                    deleteFileOrFolderSilently(fileEntry);
-                } else {
-                    fileEntry.delete();
+            if (files != null) {
+                for (File fileEntry : files) {
+                    if (fileEntry.isDirectory()) {
+                        deleteFileOrFolderSilently(fileEntry);
+                    } else {
+                        fileEntry.delete();
+                    }
                 }
             }
         }

@henrymoulton Yes, this is the patch I recommend. Besides, I also recommend to modify Line 25 for the same reason:
https://github.com/microsoft/react-native-code-push/blob/3144c916018fab077231e88d8718ad3a1cb0a7d8/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java#L25
U may refer here to see my modification.

diff --git a/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java b/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
index 29d52ec..cb6926f 100644
--- a/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
+++ b/node_modules/react-native-code-push/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java
@@ -22,7 +22,11 @@ public class FileUtils {
             destDir.mkdir();
         }

-        for (File sourceFile : sourceDir.listFiles()) {
+        File[] files = sourceDir.listFiles();
+        if (files == null) {
+            return;
+        }
+        for (File sourceFile : files) {
             if (sourceFile.isDirectory()) {
                 copyDirectoryContents(
                         CodePushUtils.appendPathComponent(sourceDirectoryPath, sourceFile.getName()),
@@ -72,6 +76,9 @@ public class FileUtils {
     public static void deleteFileOrFolderSilently(File file) {
         if (file.isDirectory()) {
             File[] files = file.listFiles();
+            if (files == null) {
+                return;
+            }
             for (File fileEntry : files) {
                 if (fileEntry.isDirectory()) {
                     deleteFileOrFolderSilently(fileEntry);

Is the patch I'm applying, will feedback how it goes

I have this issue also in production

Screen Shot 2019-09-11 at 12 28 07 PM

Thanks for the patch @henrymoulton, Has this worked for you?

Currently away, will know soon.

On Wed, 11 Sep 2019 at 10:31, Adnan Khabbaz notifications@github.com
wrote:

I have this issue also in production

[image: Screen Shot 2019-09-11 at 12 28 07 PM]
https://user-images.githubusercontent.com/1051387/64685416-a5e26400-d48f-11e9-9693-b6482a7e41e1.png

Thanks for the patch @henrymoulton https://github.com/henrymoulton, Has
this worked for you?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/microsoft/react-native-code-push/issues/1505?email_source=notifications&email_token=AHFTC7H3E3BLQRZA3GROXKDQJC3F5A5CNFSM4GRPK2PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6N4CSA#issuecomment-530301256,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AHFTC7FHETH2RQTRDE5NC3LQJC3F5ANCNFSM4GRPK2PA
.

>

Best Regards,
Henry Moulton

@adnkh no longer seeing the com.microsoft.codepush.react.FileUtils.copyDirectoryContents error but still seeing the com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently error

@coolguy001tv did your patch resolve the com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently problem?

@henrymoulton It never occurs again after using the patch. So I think it at least bypasses the com.microsoft.codepush.react.FileUtils.deleteFileOrFolderSilently crash.

We are also seeing this issue affecting numerous Huawei devices. Can anyone confirm whether the patch above (or another fix to prevent the crash) is likely to be merged into a release at some point please?

@julianD77 Sorry I can't. Since microsoft code-push is so slow in China, we have to migrate to another code-push-like solution.

Hi there.

We investigated the problem and found the following:
1) the api shouldn't return the null in cases different from when it executed against the non-folder entity https://developer.android.google.cn/reference/java/io/File#listFiles()
2) there are some cases in reality when the call returns null if there are no permission to read the catalog
3) the particular code path which attempted to be cleared out is persisted in the app folder, so no special permission are required for the app to work with that even on Android 10 and further.

Unfortunately applying the patch mentioned above in the issue is not an option, because it would just skip deletion which is not expected.

Issue affects only some devices and caused by API to behave against the specification, and may be fixed with OS updates already or be fixed in the future. Until this fixed, we don't have solid solution for the code to work as expected on those devices.

So right now I'm going just close the issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

osdnk picture osdnk  Â·  3Comments

Phredward picture Phredward  Â·  3Comments

ninjz picture ninjz  Â·  4Comments

ACCTFORGH picture ACCTFORGH  Â·  3Comments

cgerikj picture cgerikj  Â·  3Comments