Some classes and android resources are missing in the APK when android_binary depends on targets fetched with rules_jvm_external.
When building an Android App using [email protected] and [email protected] that depends on the androidx.benchmark library, classes used at runtime by androidx.benchmark library aren't bundled to the resulting APK that leads to java.lang.NoClassDefFoundError exception when running the test.
I am not 100% sure this is a bug in rules_jvm_exteranal and not in rules_android, though.
Here is the sample app with the bug description in readme: https://github.com/KirillTim/bazel_androidx_benchmarks.
Could please somebody take a look and tell me is it indeed a bug or am I doing something wrong?
Those classes indeed aren't in the final APK, because the wire-runtime itself is just a compile dep for the API, and doesn't have the impl classes:
$ jar tf /usr/local/google/home/jingwen/.cache/bazel/_bazel_jingwen/492f0d6948d26fb691fd96478138bb61/external/maven/v1/https/repo1.maven.org/maven2/com/squareup/wire/wire-runtime/4.9.7/wire-runtime-4.9.7.jar
META-INF/
META-INF/MANIFEST.MF
META-INF/kotlin-project-structure-metadata.json
commonMain/
commonMain/default/
commonMain/default/manifest
commonMain/default/linkdata/
commonMain/default/linkdata/module
commonMain/default/linkdata/package_com/
commonMain/default/linkdata/package_com/0_com.knm
commonMain/default/linkdata/package_com.squareup/
commonMain/default/linkdata/package_com.squareup/0_squareup.knm
commonMain/default/linkdata/package_com.squareup.wire/
commonMain/default/linkdata/package_com.squareup.wire/0_wire.knm
commonMain/default/linkdata/package_com.squareup.wire/1_wire.knm
commonMain/default/linkdata/package_com.squareup.wire.internal/
commonMain/default/linkdata/package_com.squareup.wire.internal/0_internal.knm
commonMain/default/linkdata/package_com.squareup.wire.internal/1_internal.knm
commonMain/default/linkdata/root_package/
commonMain/default/linkdata/root_package/0_.knm
nativeMain/
nativeMain/default/
nativeMain/default/linkdata/
nativeMain/default/linkdata/module
nativeMain/default/linkdata/package_com.squareup.wire.internal/
nativeMain/default/linkdata/package_com.squareup.wire.internal/0_internal.knm
nativeMain/default/linkdata/package_com.squareup.wire.internal/1_internal.knm
nativeMain/default/linkdata/package_com.squareup.wire/
nativeMain/default/linkdata/package_com.squareup.wire/0_wire.knm
nativeMain/default/linkdata/package_com.squareup.wire/1_wire.knm
nativeMain/default/linkdata/package_com.squareup/
nativeMain/default/linkdata/package_com.squareup/0_squareup.knm
nativeMain/default/linkdata/package_com/
nativeMain/default/linkdata/package_com/0_com.knm
nativeMain/default/linkdata/root_package/
nativeMain/default/linkdata/root_package/0_.knm
nativeMain/default/manifest
commonMain/default/resources/
nativeMain/default/targets/
nativeMain/default/targets/ios_x64/
nativeMain/default/targets/ios_x64/kotlin/
nativeMain/default/resources/
nativeMain/default/targets/ios_x64/native/
nativeMain/default/targets/ios_x64/included/
So the classes has to be somewhere else, and I found https://github.com/square/wire/issues/2215, which suggests wire-runtime-jvm.
Adding that into the direct dep of the app appears to link in the classes:
06:42:22 {main} ~/code/bazel_androidx_benchmarks/src/test
$ git diff
diff --git a/WORKSPACE b/WORKSPACE
index 129b11d..550fc2e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -22,9 +22,10 @@ maven_install(
"junit:junit:4.13.2",
"androidx.benchmark:benchmark-junit4:1.3.4",
"androidx.benchmark:benchmark-common:1.3.4",
+ "com.squareup.wire:wire-runtime-jvm:4.9.7",
],
repositories = [
"https://maven.google.com",
"https://repo1.maven.org/maven2",
],
-)
\ No newline at end of file
+)
diff --git a/src/test/BUILD.bazel b/src/test/BUILD.bazel
index c565086..61ac8bf 100644
--- a/src/test/BUILD.bazel
+++ b/src/test/BUILD.bazel
@@ -12,6 +12,7 @@ android_binary(
deps = [
# direct dependency on "@maven//:com_squareup_wire_wire_runtime" doesn't fix the problem
"@maven//:com_squareup_wire_wire_runtime",
+ "@maven//:com_squareup_wire_wire_runtime_jvm",
"@maven//:junit_junit",
"@maven//:androidx_test_runner",
"@maven//:androidx_benchmark_benchmark_junit4",
@@ -32,4 +33,4 @@ android_binary(
"@maven//:junit_junit",
"@maven//:androidx_test_runner",
],
-)
\ No newline at end of file
+)
$ jar tf ../../bazel-bin/src/test/benchmark_app_deploy.jar | grep wire
commonMain/default/linkdata/package_com.squareup.wire/
commonMain/default/linkdata/package_com.squareup.wire/0_wire.knm
commonMain/default/linkdata/package_com.squareup.wire/1_wire.knm
commonMain/default/linkdata/package_com.squareup.wire.internal/
commonMain/default/linkdata/package_com.squareup.wire.internal/0_internal.knm
commonMain/default/linkdata/package_com.squareup.wire.internal/1_internal.knm
nativeMain/default/linkdata/package_com.squareup.wire.internal/
nativeMain/default/linkdata/package_com.squareup.wire.internal/0_internal.knm
nativeMain/default/linkdata/package_com.squareup.wire.internal/1_internal.knm
nativeMain/default/linkdata/package_com.squareup.wire/
nativeMain/default/linkdata/package_com.squareup.wire/0_wire.knm
nativeMain/default/linkdata/package_com.squareup.wire/1_wire.knm
META-INF/wire-runtime.kotlin_module
com/squareup/wire/
com/squareup/wire/AndroidMessage$Companion.class
com/squareup/wire/AndroidMessage$ProtoAdapterCreator.class
com/squareup/wire/AndroidMessage.class
com/squareup/wire/AnyMessage$Companion$ADAPTER$1.class
com/squareup/wire/AnyMessage$Companion.class
com/squareup/wire/AnyMessage.class
com/squareup/wire/BuildConfigKt.class
com/squareup/wire/DoubleArrayProtoAdapter.class
com/squareup/wire/DoubleProtoAdapter.class
com/squareup/wire/DurationKt.class
com/squareup/wire/EnumAdapter.class
com/squareup/wire/EnumAdapterKt.class
...
com/squareup/wire/Message.class
...
Thanks @jin!
Adding that dependency indeed fixed the missing classes error and revealed more problems :)
The test app is now crashing because of missing resources: resources (layout.xml, AndroidManifest entries, etc) are not merged from the androidx_benchmark_benchmark_common AAR dependency to the final APK.
I've created yet another repro (the same project, but another branch): that shows the problem and workaround: https://github.com/KirillTim/bazel_androidx_benchmarks/blob/try-to-build-apk-with-aar-dep/src/test/BUILD.bazel.
Please take a look at the top UPD section of the readme: https://github.com/KirillTim/bazel_androidx_benchmarks/blob/try-to-build-apk-with-aar-dep/README.md
The interesting thing is, that the AAR dependency is not a transitive dependency, but a direct one, still not passed to the APK resources merge action.
Am I doing something wrong or miss some easier workaround?
This sounds more to do with the android rules (i.e. what aar_import propagates upwards, and what it's consumed)
Maybe @ahumesky knows?