shorebirdtech / shorebird

Code Push for Flutter and other tools for Flutter businesses.
https://shorebird.dev
Other
2.34k stars 142 forks source link

fix: Installation error: INSTALL_PARSE_FAILED_NO_CERTIFICATES #1398

Open eseidel opened 1 year ago

eseidel commented 1 year ago

Customer reported that they're building an aab on their CI and then trying to preview on their local host and hitting Installation error: INSTALL_PARSE_FAILED_NO_CERTIFICATES

Not really sure why it's happening yet.

eseidel commented 1 year ago

We believe this was a java mismatch, speculatively closing.

akiortagem-renos commented 3 weeks ago

Hi, it's happening to us too. Can you please explain what you mean by java mismatch? If it helps these are the version on my local machine

java --version
openjdk 11.0.24 2024-07-16
OpenJDK Runtime Environment Homebrew (build 11.0.24+0)
OpenJDK 64-Bit Server VM Homebrew (build 11.0.24+0, mixed mode)
javac --version
javac 11.0.24

And the log of the moment of the crash

[BT:1.17.1] Error: Installation of the app failed.
com.android.tools.build.bundletool.model.exceptions.CommandExecutionException: Installation of the app failed.
        at com.android.tools.build.bundletool.model.exceptions.InternalExceptionBuilder.build(InternalExceptionBuilder.java:57)
        at com.android.tools.build.bundletool.device.DdmlibDevice.installApks(DdmlibDevice.java:196)
        at com.android.tools.build.bundletool.commands.InstallApksCommand.lambda$execute$2(InstallApksCommand.java:236)
        at com.android.tools.build.bundletool.device.AdbRunner.run(AdbRunner.java:81)
        at com.android.tools.build.bundletool.device.AdbRunner.run(AdbRunner.java:43)
        at com.android.tools.build.bundletool.commands.InstallApksCommand.execute(InstallApksCommand.java:236)
        at com.android.tools.build.bundletool.BundleToolMain.main(BundleToolMain.java:117)
        at com.android.tools.build.bundletool.BundleToolMain.main(BundleToolMain.java:55)
Caused by: com.android.ddmlib.InstallException: Failed to commit install session 189164924 with command package install-commit 189164924. Error: INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from /data/app/vmdl189164924.tmp/universal.apk: Attempt to get length of null array
        at com.android.ddmlib.SplitApkInstallerBase.installCommit(SplitApkInstallerBase.java:154)
        at com.android.ddmlib.SplitApkInstaller.install(SplitApkInstaller.java:85)
        at com.android.ddmlib.IDeviceSharedImpl.installPackages(IDeviceSharedImpl.java:395)
        at com.android.ddmlib.internal.DeviceImpl.lambda$installPackages$34(DeviceImpl.java:1484)
        at com.android.ddmlib.internal.DeviceImpl.logRun3(DeviceImpl.java:1826)
        at com.android.ddmlib.internal.DeviceImpl.installPackages(DeviceImpl.java:1481)
        at com.android.tools.build.bundletool.device.DdmlibDevice.installApks(DdmlibDevice.java:180)
        ... 6 more
akiortagem-renos commented 2 weeks ago

Hi, any news on this? Can anything be done on our side? We're looking forward to use Shorebird to deploy emergency patches in cases of high profile events that drives traffic to our flutter app.

bryanoltman commented 2 weeks ago

@akiortagem-renos Sorry for the delay. We have not had time to look into this issue. If you can share reproduction steps, including:

  1. The exact shorebird commands you ran
  2. Any relevant info about your development environment (e.g., which OS you're using)
  3. The output of shorebird doctor -v

We'd be happy to take a look.

akiortagem-renos commented 2 weeks ago

Hi @bryanoltman , thanks for responding. The OS I'm running shorebird on is macOS Sonoma 14.4.1

This is the output of shorebird doctor -v

Shorebird 1.4.8 • git@github.com:shorebirdtech/shorebird.git
Flutter 3.24.4 • revision de629bcb9c96360eb3ca20fcc045263c19b1a33d
Engine • revision edb175f4b6894b63d8217952f0e4f59adb97a7e2

Logs: /Users/renosmacbookair/Library/Application Support/shorebird/logs
Android Toolchain
  • Android Studio: /Applications/Android Studio.app/Contents
  • Android SDK: /Users/renosmacbookair/Library/Android/sdk
  • ADB: /Users/renosmacbookair/Library/Android/sdk/platform-tools/adb
  • JAVA_HOME: /Applications/Android Studio.app/Contents/jbr/Contents/Home
  • JAVA_EXECUTABLE: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
  • JAVA_VERSION: openjdk version "17.0.6" 2023-01-17
                  OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
                  OpenJDK 64-Bit Server VM (build 17.0.6+0-17.0.6b802.4-9586694, mixed mode)

  • Gradle: 7.6.3

URL Reachability
✓ https://api.shorebird.dev OK (0.3s)
✓ https://console.shorebird.dev OK (0.6s)
✓ https://oauth2.googleapis.com OK (0.2s)
✓ https://storage.googleapis.com OK (0.1s)
✓ https://cdn.shorebird.cloud OK (91ms)

Network Speed
✓ GCP Upload Speed: 1.75 MB/s (3.2s)
✓ GCP Download Speed: 2.33 MB/s (7.1s)

✓ Shorebird is up-to-date (1.5s)
✓ Flutter install is correct (0.6s)
✓ AndroidManifest.xml files contain INTERNET permission (41ms)
✓ shorebird.yaml found in pubspec.yaml assets (9ms)

No issues detected!

I tried to ran preview after release. These are the chain of the exact commands and their output

$ shorebird release android --flavor=staging --dart-define flavor="staging" --build-number="2002" --build-name="0.1.0"
Updating Flutter...
Cloning into '/Users/renosmacbookair/.shorebird/bin/cache/flutter/de629bcb9c96360eb3ca20fcc045263c19b1a33d'...
remote: Enumerating objects: 43924, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 43924 (delta 0), reused 4 (delta 0), pack-reused 43920 (from 1)
Receiving objects: 100% (43924/43924), 25.76 MiB | 2.59 MiB/s, done.
Resolving deltas: 100% (2049/2049), done.
remote: Enumerating objects: 2012, done.
remote: Counting objects: 100% (546/546), done.
remote: Compressing objects: 100% (469/469), done.
remote: Total 2012 (delta 109), reused 81 (delta 77), pack-reused 1466 (from 1)
Receiving objects: 100% (2012/2012), 339.08 KiB | 410.00 KiB/s, done.
Resolving deltas: 100% (124/124), done.
remote: Enumerating objects: 6945, done.
remote: Counting objects: 100% (4784/4784), done.
remote: Compressing objects: 100% (4085/4085), done.
remote: Total 6945 (delta 1627), reused 699 (delta 698), pack-reused 2161 (from 1)
Receiving objects: 100% (6945/6945), 13.17 MiB | 2.46 MiB/s, done.
Resolving deltas: 100% (2136/2136), done.
Updating files: 100% (8621/8621), done.
HEAD is now at de629bcb chore: roll engine to `edb175f4b6894b63d8217952f0e4f59adb97a7e2` (3.24.4)
Shorebird Engine • revision edb175f4b6894b63d8217952f0e4f59adb97a7e2
Downloading Darwin arm64 Dart SDK from Flutter engine edb175f4b6894b63d8217952f0e4f59adb97a7e2...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 78.2M  100 78.2M    0     0  4410k      0  0:00:18  0:00:18 --:--:-- 5892k
Building flutter tool...
Resolving dependencies... (1.8s)
Downloading packages... 
Got dependencies.
Flutter 3.24.5-0.0.pre.4 • channel [user-branch] • unknown source
Framework • revision de629bcb9c (34 hours ago) • 2024-10-28 12:03:56 -0500
Engine • revision edb175f4b6
Tools • Dart 3.5.4 • DevTools 2.37.0
Building Shorebird...
Resolving dependencies... (6.0s)
Downloading packages... 
Got dependencies.
✓ Downloading aot-tools.dill... (0.4s)
✓ Extracting aot-tools.dill... (8.6s)
✓ Fetching apps (0.5s)
✓ Building app bundle with Flutter 3.24.4 (de629bcb9c) (240.6s)
✓ Release version: 0.1.0-staging+2002 (1.4s)
✓ Fetching releases (0.5s)

🚀 Ready to create a new release!

📱 App: renos_mobile (staging) (c1e66009-aa2a-43f3-989f-6692cd96bd2b)
🍧 Flavor: staging
📦 Release Version: 0.1.0-staging+2002
🕹️  Platform: android
🐦 Flutter Version: 3.24.4 (de629bcb9c)

Would you like to continue? (y/N) Yes
✓ Fetching releases (0.3s)
✓ Creating release (0.8s)
✓ Updating release status (0.3s)
✓ Uploading artifacts (33.0s)
✓ Updating release status (2.0s)

✅ Published Release 0.1.0-staging+2002!
Your next step is to upload the app bundle to the Play Store:
/Users/renosmacbookair/Work/renos-mobile/apps/rns_buyer/build/app/outputs/bundle/stagingRelease/app-staging-release.aab

For information on uploading to the Play Store, see:
https://support.google.com/googleplay/android-developer/answer/9859152?hl=en

To create a patch for this release, run shorebird patch --platforms=android --flavor=staging --release-version=0.1.0-staging+2002

Note: shorebird patch --platforms=android --flavor=staging without the --release-version option will patch the current version of the app.

and then

$ shorebird preview --verbose                                                                                         
Which app flavor? staging
[HTTP] GET https://api.shorebird.dev/api/v1/apps/c1e66009-aa2a-43f3-989f-6692cd96bd2b/releases
[HTTP] GET https://api.shorebird.dev/api/v1/apps/c1e66009-aa2a-43f3-989f-6692cd96bd2b/releases?sideloadable=true
✓ Fetching releases (0.4s)
✓ Fetching releases (0.4s)
Which release would you like to preview? 0.1.0-staging+2002
[HTTP] GET https://api.shorebird.dev/api/v1/apps/c1e66009-aa2a-43f3-989f-6692cd96bd2b/releases/119087/artifacts?arch=aab&platform=android
✓ Fetching aab artifact (0.3s)
✓ Downloading release (0.3s)
✓ Using production track (1.0s)
No checksum provided for patch, skipping file corruption validation
No checksum provided for aot-tools.dill, skipping file corruption validation
[Process.run] /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Users/renosmacbookair/.shorebird/bin/cache/artifacts/bundletool/bundletool.jar dump manifest --bundle=/Users/renosmacbookair/.shorebird/bin/cache/previews/c1e66009-aa2a-43f3-989f-6692cd96bd2b/android_0.1.0-staging+2002_466535.aab --xpath /manifest/@package
⠴ Extracting metadata... (0.6s)Exited with code 0

stdout:
com.renos.mobile.staging

✓ Extracting metadata (0.7s)
No checksum provided for patch, skipping file corruption validation
No checksum provided for aot-tools.dill, skipping file corruption validation
[Process.run] /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Users/renosmacbookair/.shorebird/bin/cache/artifacts/bundletool/bundletool.jar build-apks --overwrite --bundle=/Users/renosmacbookair/.shorebird/bin/cache/previews/c1e66009-aa2a-43f3-989f-6692cd96bd2b/android_0.1.0-staging+2002_466535.aab --output=/Users/renosmacbookair/.shorebird/bin/cache/previews/c1e66009-aa2a-43f3-989f-6692cd96bd2b/android_0.1.0-staging+2002_466535.apks --mode=universal
⠇ Building apks... (3.3s)Exited with code 0

stdout:
WARNING: The APKs won't be signed and thus not installable unless you also pass a keystore via the flag --ks. See the command help for more information.

✓ Built apks: /Users/renosmacbookair/.shorebird/bin/cache/previews/c1e66009-aa2a-43f3-989f-6692cd96bd2b/android_0.1.0-staging+2002_466535.apks (3.3s)
No checksum provided for patch, skipping file corruption validation
No checksum provided for aot-tools.dill, skipping file corruption validation
[Process.run] /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java -jar /Users/renosmacbookair/.shorebird/bin/cache/artifacts/bundletool/bundletool.jar install-apks --apks=/Users/renosmacbookair/.shorebird/bin/cache/previews/c1e66009-aa2a-43f3-989f-6692cd96bd2b/android_0.1.0-staging+2002_466535.apks --allow-downgrade
⠧ Installing apks... (2.4s)Exited with code 1

stdout:
10:18:36 E/SplitApkInstallerBase: Failed to commit install session 672534927 with command package install-commit 672534927. Error: INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collecy

stderr:
The APKs have been extracted in the directory: /var/folders/tj/x187t0m957s1ktmtpvjbcnb00000gn/T/182524584928707157
[BT:1.17.1] Error: Installation of the app failed.
com.android.tools.build.bundletool.model.exceptions.CommandExecutionException: Installation of the app failed.
        at com.android.tools.build.bundletool.model.exceptions.InternalExceptionBuilder.build(InternalExceptionBuilder.java:57)
        at com.android.tools.build.bundletool.device.DdmlibDevice.installApks(DdmlibDevice.java:196)
        at com.android.tools.build.bundletool.commands.InstallApksCommand.lambda$execute$2(InstallApksCommand.java:236)
        at com.android.tools.build.bundletool.device.AdbRunner.run(AdbRunner.java:81)
        at com.android.tools.build.bundletool.device.AdbRunner.run(AdbRunner.java:43)
        at com.android.tools.build.bundletool.commands.InstallApksCommand.execute(InstallApksCommand.java:236)
        at com.android.tools.build.bundletool.BundleToolMain.main(BundleToolMain.java:117)
        at com.android.tools.build.bundletool.BundleToolMain.main(BundleToolMain.java:55)
Caused by: com.android.ddmlib.InstallException: Failed to commit install session 672534927 with command package install-commit 672534927. Error: INSTALL_PARSE_FAILED_NO_CERTIFICATES: Fay
        at com.android.ddmlib.SplitApkInstallerBase.installCommit(SplitApkInstallerBase.java:154)
        at com.android.ddmlib.SplitApkInstaller.install(SplitApkInstaller.java:85)
        at com.android.ddmlib.IDeviceSharedImpl.installPackages(IDeviceSharedImpl.java:395)
        at com.android.ddmlib.internal.DeviceImpl.lambda$installPackages$34(DeviceImpl.java:1484)
        at com.android.ddmlib.internal.DeviceImpl.logRun3(DeviceImpl.java:1826)
        at com.android.ddmlib.internal.DeviceImpl.installPackages(DeviceImpl.java:1481)
        at com.android.tools.build.bundletool.device.DdmlibDevice.installApks(DdmlibDevice.java:180)
        ... 6 more

✗ Exception: Failed to install apks: The APKs have been extracted in the directory: /var/folders/tj/x187t0m957s1ktmtpvjbcnb00000gn/T/182524584928707157
[BT:1.17.1] Error: Installation of the app failed.
com.android.tools.build.bundletool.model.exceptions.CommandExecutionException: Installation of the app failed.
        at com.android.tools.build.bundletool.model.exceptions.InternalExceptionBuilder.build(InternalExceptionBuilder.java:57)
        at com.android.tools.build.bundletool.device.DdmlibDevice.installApks(DdmlibDevice.java:196)
        at com.android.tools.build.bundletool.commands.InstallApksCommand.lambda$execute$2(InstallApksCommand.java:236)
        at com.android.tools.build.bundletool.device.AdbRunner.run(AdbRunner.java:81)
        at com.android.tools.build.bundletool.device.AdbRunner.run(AdbRunner.java:43)
        at com.android.tools.build.bundletool.commands.InstallApksCommand.execute(InstallApksCommand.java:236)
        at com.android.tools.build.bundletool.BundleToolMain.main(BundleToolMain.java:117)
        at com.android.tools.build.bundletool.BundleToolMain.main(BundleToolMain.java:55)
Caused by: com.android.ddmlib.InstallException: Failed to commit install session 672534927 with command package install-commit 672534927. Error: INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from /data/app/vmdl672534927.tmp/universal.apk: Attempt to get length of null array
        at com.android.ddmlib.SplitApkInstallerBase.installCommit(SplitApkInstallerBase.java:154)
        at com.android.ddmlib.SplitApkInstaller.install(SplitApkInstaller.java:85)
        at com.android.ddmlib.IDeviceSharedImpl.installPackages(IDeviceSharedImpl.java:395)
        at com.android.ddmlib.internal.DeviceImpl.lambda$installPackages$34(DeviceImpl.java:1484)
        at com.android.ddmlib.internal.DeviceImpl.logRun3(DeviceImpl.java:1826)
        at com.android.ddmlib.internal.DeviceImpl.installPackages(DeviceImpl.java:1481)
        at com.android.tools.build.bundletool.device.DdmlibDevice.installApks(DdmlibDevice.java:180)
        ... 6 more
 (2.5s)
[Process.run] git symbolic-ref HEAD (in /Users/renosmacbookair/.shorebird/bin/cache)
Exited with code 0

stdout:
refs/heads/stable

[Process.run] git rev-parse --verify HEAD (in /Users/renosmacbookair/.shorebird/bin/cache)
Exited with code 0

stdout:
284eb5a1af9a4c6e9195def5ff5905dae779a1cc

[Process.run] git remote prune origin (in /Users/renosmacbookair/.shorebird/bin/cache)
Exited with code 0
[Process.run] git fetch --tags (in /Users/renosmacbookair/.shorebird/bin/cache)
Exited with code 0
[Process.run] git rev-parse --verify @{upstream} (in /Users/renosmacbookair/.shorebird/bin/cache)
Exited with code 0

stdout:
284eb5a1af9a4c6e9195def5ff5905dae779a1cc
bryanoltman commented 2 weeks ago

WARNING: The APKs won't be signed and thus not installable unless you also pass a keystore via the flag --ks. See the command help for more information. seems relevant. I believe this is happening because you haven't set up signing for your app in release mode. In your app's android/app/build.gradle file, you should see a section that looks like:

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig = signingConfigs.debug
        }
    }

Can you verify that this is present?

akiortagem-renos commented 2 weeks ago

Hi @bryanoltman, we've set that up ages ago. But, yea we're not sure if this would work with shorebird. Here's what we have currently

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

signingConfigs {
    debug {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
    profile {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
}

buildTypes {
    debug {
        signingConfig signingConfigs.debug
    }
    profile {
        signingConfig signingConfigs.debug
    }
    release {
        signingConfig signingConfigs.release
    }
  }
bryanoltman commented 2 weeks ago

Hmm, that all looks like it should work with Shorebird just fine (although you have the exact same signing configs for all three modes and you're using the debug signing config for the profile build type).

Do you see any error messages or warnings related to signing when you make a release? If not, would you mind checking the log file for the release build? shorebird doctor -v will print the path to our logs directory (for me, the line is: Logs: /Users/bryanoltman/Library/Application Support/shorebird/logs), and the relevant log file will start with the timestamp when the command was run (the command should also be the first line of the file).

akiortagem-renos commented 2 weeks ago

Oh we cycle key.properties on actual CI/CD. On local machines, we use staging keys, regardless of which profile.

I'm not seeing any exception/errors on the log, but I might miss something important. The full logs is here 1730257712718_shorebird.log

akiortagem-renos commented 1 week ago

Any news on this? any help would be greatly appreciated

eseidel commented 1 week ago

My understanding is that this happens when the .apk isn't properly signed.

All shorebird preview does, is download the previously built .aab file (available on https://console.shorebird.dev/ for download) and the runs bundle-tool build-apks and bundletool install-apks. bundletool build-apks will use the gradle files present to find the keystore for and sign the built apks with the available keystore. https://github.com/shorebirdtech/shorebird/blob/6704e56666dff10e1bc002a18838a7337245c008/packages/shorebird_cli/lib/src/commands/preview_command.dart#L362

https://developer.android.com/tools/bundletool#generate_apks

My guess is that in these failing cases, the local keystores are not present?

eseidel commented 1 week ago

I am not an expert on bundletool, so it's possible I'm misunderstanding how it interacts with the keystores.

bryanoltman commented 1 week ago

Oh we cycle key.properties on actual CI/CD. On local machines, we use staging keys, regardless of which profile.

I'm not seeing any exception/errors on the log, but I might miss something important. The full logs is here 1730257712718_shorebird.log

This looks like a successful release. There's output indicating the aab is signed:

⠹ Building app bundle with Flutter 3.24.4 (de629bcb9c) Task :app:signStagingReleaseBundle... (234.7s)

You've verified that you have a local key.properties and that it's the same as what is being used to sign the bundle?

akiortagem-renos commented 1 week ago

Yes, we have the key.properties on my local machine, and it is indeed the same as what's being used to sign the bundle. The keystores exists as well.

eseidel commented 1 week ago

https://stackoverflow.com/questions/2914105/what-is-install-parse-failed-no-certificates-error is the best info I've found on this error. Unclear to me if there is something Shorebird is doing wrong to create this error or if this is something in the gradle setup.

akiortagem-renos commented 6 days ago

@eseidel right, thanks for the guidance. I'll delve into them and get back to you guys. Thanks heaps!