Signing APK causes error "Failed to extract native libraries – 'libsqlite3_python.so' is not page-aligned"
Describe the bug
Installing release APK with adb install dist/Hello World-0.0.1.apk results in INSTALL_FAILED_INVALID_APK, while installing debug APK with adb install dist/Hello World-0.0.1.debug.apk has no issue.
The release APK was properly signed using
Steps to reproduce
- Create clean new environment with
python -m venv beeware-venv - Activate new environement
source beeware-venv/bin/activate - Create briefcase project with all values to default
briefcase new - Create android platform
briefcase create android - Package android
briefcase package android -p apk - Sign APK with previously created
upload-key-hellow_world.jkskey using~/.cache/briefcase/tools/java17/bin/jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ~/.local/share/android/upload-key-hello_world.jks "dist/Hello World-0.0.1.apk" upload-key -storepass android - Install apk on device with
adb install dist/Hellow World-0.0.1.apk(emulator or physical device behave the same) - Results in
adb: failed to install dist/Hello World-0.0.1.apk: Failure [INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2]
Expected behavior
The APK should install without any issues as it correctly happen when installing debug version of the APK.
Screenshots
No response
Environment
- Operating System: ArchLinux (6.13.1-arch1-1)
- Python version: 3.13.1
- Software versions:
- Briefcase: 0.3.31
Logs
logcat section I believe to be relevant :
02-06 10:59:31.048 1357 1357 I abb : StartCommandInProcess(73657474696e67730067657400676c6f settings.get.glo [truncated])
02-06 10:59:31.049 557 557 W Binder:557_12: type=1400 audit(0.0:333): avc: denied { getopt } for scontext=u:r:system_server:s0 tcontext=u:r:shell:s0 tclass=unix_stream_socket permissive=0
02-06 10:59:31.057 1357 1357 I abb : StartCommandInProcess(7061636b61676500696e7374616c6c00 package.install. [truncated])
02-06 10:59:31.049 557 557 W Binder:557_12: type=1400 audit(0.0:334): avc: denied { getopt } for scontext=u:r:system_server:s0 tcontext=u:r:shell:s0 tclass=unix_stream_socket permissive=0
02-06 10:59:31.049 557 557 W Binder:557_12: type=1400 audit(0.0:335): avc: denied { getopt } for scontext=u:r:system_server:s0 tcontext=u:r:shell:s0 tclass=unix_stream_socket permissive=0
02-06 10:59:31.369 557 557 W Binder:557_12: type=1400 audit(0.0:336): avc: denied { getopt } for scontext=u:r:system_server:s0 tcontext=u:r:shell:s0 tclass=unix_stream_socket permissive=0
02-06 10:59:31.557 557 643 E NativeLibraryHelper: Library 'libsqlite3_python.so' is not page-aligned - will not be able to open it directly from apk.
02-06 10:59:31.557 557 643 W NativeHelper: Failure copying native libraries [errorCode=-2]
02-06 10:59:31.557 557 643 E PackageInstallerSession: Failed to verify session 1347179052 [INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2]
02-06 10:59:31.569 446 474 E installd: Couldn't opendir /data/app/vmdl1347179052.tmp: No such file or directory
02-06 10:59:31.569 446 474 E installd: Failed to delete /data/app/vmdl1347179052.tmp: No such file
Additional context
No response
Likely dup:
- https://github.com/beeware/briefcase/issues/2135
Thanks for the report - Library 'libsqlite3_python.so' is not page-aligned definitely seems to point to the root cause. How that has happened is another question...
Can you provide details about the Android device you're deploying to (Make, model, Android version etc)?
My guess is that this is related to the 16kB page size transition that Android is currently in the process of rolling out. If the signing process is rewriting the binary, it's possible that is corrupting the binary by not honouring 16kB page sizes in the rewritten, signed version. I'm not sure what the fix is here; does that sound plausible as an explanation @mhsmith?
Thanks for you answer @freakboy3742.
The physical device is a Motorola edge 50 fusion (XT2429-2) with Android 15 (Noyau 5.10.218-android2-9-00025-g7e8d2909ab18-ab12292143).
The emulator is on Android Version 12. It has a build number of sdk_phone64_x86_64-userdebug 12 SE1A_220826.006.A1 10064458 test-keys.
Likely dup:
I'm not sure about that – the error message is completely different.
My guess is that this is related to the 16kB page size transition that Android is currently in the process of rolling out.
No, that's only reached experimental emuator images so far, not physical devices.
The APK should be page-aligned automatically by Gradle. However, based on the orange warning at the top of this page, the alignment can be broken if the APK is subsequently modified by jarsigner. It sounds like there's a newer tool called apksigner which doesn't have this problem, so maybe we should update the Briefcase documentation to recommend that.
/me grumbles about the state of Android's toolchain documentation.
Given that we're not explicitly invoking zipalign, and Gradle goes to extraordinary lengths to both fill the screen with content and yet not tell you what it's actually doing, I'm not sure how we're meant to know whether we're invoking zipalign.
However, it seems plausible that this might be the source of the problem.
Now we just need to find the magic instructions on how to actually use apksigner. Because, of course, the actual apksigner documentation gives a dozen ways it could be invoked, but neglects to highlight "...and this is the one way you'll actually need to use it to submit an app to the Play Store, which the only use case 99% of users actually give a damn about".
I have android-sdk-build-tools-latest installed on my computer (that would be version 35 of the SDK), apksigner comes with it. I'll try using it and see if this changes something.
/me grumbles about the state of Android's toolchain documentation.
Yes, a lot of these command-line tools are poorly documented because you're really supposed to use them via Gradle. There are some notes in #1268 about how that would work.
I signed the APK with apksigner using the following command :
apksigner sign --ks ~/.local/share/android/upload-key-hellow_world.jks "dist/Hello world.0.0.1.apk"
This asks for the password of the keystore which was given with keytool as android.
This solves the issue, the APK is installed.
Thanks for the update. Let's leave the issue open as a reminder to fix the documentation, until we're able to add code to Briefcase to fully automate this (#1268).