Android rules not working properly with exported Java plugins
Kernald opened this issue · comments
Following Dagger's recommended Hilt integration, when using this android_library
target with the following Java class, the code generation runs fine:
android_library(
name = "app",
srcs = ["SampleApplication.java"],
manifest = "AndroidManifest.xml",
deps = [
":res",
"//third_party/dagger/hilt:hilt-android",
],
)
package fr.enoent.android.sample;
import android.app.Application;
import dagger.hilt.android.HiltAndroidApp;
@HiltAndroidApp(Application.class)
public class SampleApplication extends Sample_BurgApplication {
}
The exact same set-up with a kt_android_library
, however, doesn't end up calling the plugins exported by //third_party/dagger/hilt:hilt-android
at all. Even when only passing the same Java file to kt_android_library
- the compilation fails because the generated superclass isn't generated.
From there, I tried passing the plugins explicitly to the kt_android_library
's plugins
attribute. With a Java file, they don't seem to run at all either (maybe expected?). With a Kotlin file, some seem to run, but either not all or not in the correct order, I'm really not familiar enough with annotation processors to understand what's going on there - one of the Hilt plugins fails because the superclass hasn't been generated.
I'm not sure how much of that is working as intended, but it's a strong behavioural difference from the native android_library
(and I believe kt_jvm_library
as well?).
Btw, I noticed, if kt_android_library
has //:dagger
dependency all corresponding _Factory
s are generated. dagger
target is java_library
, while //:hilt-android
is android_library
.
It seems one can lose android_library.exported_plugins
in:
So, I changed the line to:
elif ctx.rule.kind in ["java_library", "android_library"]:
Now I started to get compilation errors from Hilt:
error: [Hilt]
public final class MyApplication {
^
@HiltAndroidApp class expected to extend Hilt_MyApplication. Found: Object
But with no luck to resolve them yet. Looks like code generation still not working.
I've come upon the same issue when using dagger_android_rules
. These also wrap a java_plugin
in android_library
, but unlike with Hilt there is only one processor class.
As @geaden wrote plugins.bzl quite clearly doesn't handle android_library
rules. I was able to reproduce the issue here and make the tests pass again with the proposed fix. Not sure why Hilt is still failing, it might be a separate issue.
Here is a demo app to demonstrate that hilt annotation processors are not running.
@geaden Sorry I edited the code I posted to keep things at their simplest and made a typo there - the code in my initial comment is indeed incorrect, but what I have locally is correct. I'll give that fix a try asap.
@geaden I tried this fix and get a similar error as above about the app class extending Object
. I'm not really sure what's running or not, or if Hilt is running on the wrong jar maybe...
@Kernald Thanks a lot for letting know! I thought I had wrong Hilt setup. I keep digging into the issue, but unsuccessfully so far.
This is a long-standing issue, it seems, related to how the rules collect plugin info - we special case java_library, and don't special case android_library. This is wrong, but it's been wrong for years. We should (and will) roll a fix, but it pre-exists, and we won't block 1.5 for it.
That said, it's awful and we should roll a fix. I'll try to get it in before release, but no promises. However, it should be in 1.6, now that we understand it.
Sorry, do we have any progress here?
Bumping up this thread again to see if there is any proper way to solve the issue.
TLDR; Hilt's library annotation processing doesn't work on kt_android_library
's Kotlin files.
Are you still able to reproduce this on a newer version of Bazel where the JavaPluginInfo
provider exists? When rules_kotlin
has access to this new provider, it doesn't apply the kt_jvm_plugin_aspect
and collects the JavaPluginInfo
directly.
Haven't made a separate demo app, but I'm seeing this as well. However, it seems like the kt_android_library
rule builds but the android_binary
depending on that rule now has the issue.
Bazel version:
❯ bazel --version
bazel 6.0.0-pre.20220608.2
kt_android_library
:
❯ bazel build //android/app/src/com/highgravitydays/android:highgravity
DEBUG: /private/var/tmp/_bazel_vple/f3403029ac4265720a1f6e63b005c1fd/external/io_bazel_rules_kotlin/kotlin/kotlin.bzl:104:10: kt_jvm_library should be loaded from //kotlin:jvm.bzl
INFO: Analyzed target //android/app/src/com/highgravitydays/android:highgravity (76 packages loaded, 1488 targets configured).
INFO: Found 1 target...
INFO: From Merging manifest for //android/app/src/com/highgravitydays/android:highgravity_base:
Warning: /private/var/tmp/_bazel_vple/f3403029ac4265720a1f6e63b005c1fd/sandbox/darwin-sandbox/784/execroot/__main__/android/app/src/com/highgravitydays/android/AndroidManifest.xml:32:9-35:35 Warning:
provider#androidx.startup.InitializationProvider was tagged at AndroidManifest.xml:32 to remove other declarations but no other declaration present
INFO: From Merging compiled Android resources for //android/app/src/com/highgravitydays/android:highgravity_base:
Warning: /private/var/tmp/_bazel_vple/f3403029ac4265720a1f6e63b005c1fd/sandbox/darwin-sandbox/1024/execroot/__main__/bazel-out/darwin_arm64-fastbuild/bin/android/app/src/com/highgravitydays/android/_renamed/highgravity_base/AndroidManifest.xml:37:9-40:35 Warning:
provider#androidx.startup.InitializationProvider was tagged at AndroidManifest.xml:37 to remove other declarations but no other declaration present
Target //android/app/src/com/highgravitydays/android:highgravity up-to-date:
bazel-bin/android/app/src/com/highgravitydays/android/libhighgravity.jar
INFO: Elapsed time: 28.413s, Critical Path: 8.58s
INFO: 455 processes: 13 internal, 440 darwin-sandbox, 2 worker.
INFO: Build completed successfully, 455 total actions
android_binary
:
❯ bazel build //android/app:app
INFO: Build option --fat_apk_cpu has changed, discarding analysis cache.
DEBUG: /private/var/tmp/_bazel_vple/f3403029ac4265720a1f6e63b005c1fd/external/io_bazel_rules_kotlin/kotlin/kotlin.bzl:104:10: kt_jvm_library should be loaded from //kotlin:jvm.bzl
INFO: Analyzed target //android/app:app (81 packages loaded, 1839 targets configured).
INFO: Found 1 target...
ERROR: /Users/vple/climb/android/app/src/com/highgravitydays/android/BUILD.bazel:5:19: KotlinKapt //android/app/src/com/highgravitydays/android:highgravity_kt { kt: 31, java: 0, srcjars: 0 } for armeabi-v7a failed: (Exit 1): build failed: error executing command (from target //android/app/src/com/highgravitydays/android:highgravity_kt) bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/io_bazel_rules_kotlin/src/main/kotlin/build ... (remaining 1 argument skipped)
error: /var/folders/tc/qpt243215ss5h5x4qf_xl86w0000gn/T/pwd10869448029639228200/_kotlinc/android_app_src_com_highgravitydays_android-highgravity_kt_jvm/temp/stubs/com/highgravitydays/android/HighGravityApplication.java:7: error: [Hilt]
public final class HighGravityApplication {
^
@HiltAndroidApp class expected to extend Hilt_HighGravityApplication. Found: Object
[Hilt] Processing did not complete. See error above for details.
android/app/src/com/highgravitydays/android/HighGravityApplication.kt:7:32: error: unresolved reference: Hilt_HighGravityApplication
class HighGravityApplication : Hilt_HighGravityApplication() {
^
Sep 29, 2022 11:06:50 PM worker request 0
SEVERE: Compilation failure: compile phase failed:Target //android/app:app failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 11.936s, Critical Path: 9.45s
INFO: 38 processes: 11 internal, 27 darwin-sandbox.
FAILED: Build did NOT complete successfully
The android_binary
has the kt_android_rule
as its only dep:
android_binary(
name = "app",
srcs = [],
custom_package = "com.highgravitydays.android",
dex_shards = 2,
manifest = "//android/app/src/com/highgravitydays/android:AndroidManifest.xml",
manifest_values = {
"versionCode": "1",
"minSdkVersion": "24",
"targetSdkVersion": "31",
},
multidex = "native",
deps = ["//android/app/src/com/highgravitydays/android:highgravity"],
)
Okay, I forked @geaden's demo and attempted to update all the build config to match my project. MyActivity
and MyApplication
were updated to extend the corresponding Hilt_*
classes, otherwise I left the app as is. Hopefully I didn't miss something.
https://github.com/vple/bazel_hilt_demo
Building the kt_android_library
and android_binary
targets seems to have a similar result to my above post--the kt_android_library
builds but the android_binary
does not.
❯ bazel clean
INFO: Starting clean.
INFO: Multiplexer process for Javac has closed its output stream
❯ bazel build //kotlin/com/example/app:examplelib
INFO: Analyzed target //kotlin/com/example/app:examplelib (69 packages loaded, 1219 targets configured).
INFO: Found 1 target...
Target //kotlin/com/example/app:examplelib up-to-date:
bazel-bin/kotlin/com/example/app/libexamplelib.jar
INFO: Elapsed time: 9.347s, Critical Path: 4.35s
INFO: 165 processes: 10 internal, 153 darwin-sandbox, 2 worker.
INFO: Build completed successfully, 165 total actions
❯ bazel build //:exampleapp
INFO: Analyzed target //:exampleapp (5 packages loaded, 449 targets configured).
INFO: Found 1 target...
INFO: From Dexing external/maven/_dx/androidx_viewpager_viewpager/classes_and_libs_merged.jar_desugared.jar with applicable dexopts []:
Info: Stripped invalid locals information from 1 method.
Info in bazel-out/android-armeabi-v7a-fastbuild/bin/external/maven/_dx/androidx_viewpager_viewpager/classes_and_libs_merged.jar_desugared.jar:androidx/viewpager/widget/PagerTitleStrip.class:
Methods with invalid locals information:
void androidx.viewpager.widget.PagerTitleStrip.updateTextPositions(int, float, boolean)
Information in locals-table is invalid with respect to the stack map table. Local refers to non-present stack map type for register: 37 with constraint INT.
Info: Some warnings are typically a sign of using an outdated Java toolchain. To fix, recompile the source with an updated toolchain.
INFO: From Dexing external/maven/_dx/androidx_compose_ui_ui/classes_and_libs_merged.jar_desugared.jar with applicable dexopts []:
Info: Stripped invalid locals information from 1 method.
Info in bazel-out/android-armeabi-v7a-fastbuild/bin/external/maven/_dx/androidx_compose_ui_ui/classes_and_libs_merged.jar_desugared.jar:androidx/compose/ui/input/pointer/util/VelocityTracker.class:
Methods with invalid locals information:
long androidx.compose.ui.input.pointer.util.VelocityTracker.getImpulseVelocity-9UxMQ8M()
Information in locals-table is invalid with respect to the stack map table. Local refers to non-present stack map type for register: 8 with constraint LONG.
Info: Some warnings are typically a sign of using an outdated Java toolchain. To fix, recompile the source with an updated toolchain.
ERROR: /Users/vple/bazel_hilt_demo/kotlin/com/example/app/BUILD:3:19: KotlinKapt //kotlin/com/example/app:examplelib_kt { kt: 4, java: 0, srcjars: 0 } for armeabi-v7a failed: (Exit 1): build failed: error executing command (from target //kotlin/com/example/app:examplelib_kt)
(cd /private/var/tmp/_bazel_vple/5076266c303c1ab027859b6e56989c6e/execroot/__main__ && \
exec env - \
LC_CTYPE=en_US.UTF-8 \
REPOSITORY_NAME=io_bazel_rules_kotlin \
bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/io_bazel_rules_kotlin/src/main/kotlin/build '--flagfile=bazel-out/android-armeabi-v7a-fastbuild/bin/kotlin/com/example/app/examplelib_kt-kapt-gensrc.jar-0.params')
# Configuration: a38a52272c28682b0c767b8d11bd23502b8f8836f39cc636f916800bb17781dc
# Execution platform: @local_config_platform//:host
error: /var/folders/tc/qpt243215ss5h5x4qf_xl86w0000gn/T/pwd12205052944019787285/_kotlinc/kotlin_com_example_app-examplelib_kt_jvm/temp/stubs/com/example/app/MyActivity.java:7: error: [Hilt]
public final class MyActivity {
^
@AndroidEntryPoint class expected to extend Hilt_MyActivity. Found: Object
[Hilt] Processing did not complete. See error above for details.
error: /var/folders/tc/qpt243215ss5h5x4qf_xl86w0000gn/T/pwd12205052944019787285/_kotlinc/kotlin_com_example_app-examplelib_kt_jvm/temp/stubs/com/example/app/MyApplication.java:7: error: [Hilt]
public final class MyApplication {
^
@HiltAndroidApp class expected to extend Hilt_MyApplication. Found: Object
[Hilt] Processing did not complete. See error above for details.
kotlin/com/example/app/MyActivity.kt:10:20: error: unresolved reference: Hilt_MyActivity
class MyActivity : Hilt_MyActivity() {
^
kotlin/com/example/app/MyActivity.kt:12:43: error: unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public inline fun <reified VM : ViewModel> ComponentActivity.viewModels(noinline extrasProducer: (() -> CreationExtras)? = ..., noinline factoryProducer: (() -> ViewModelProvider.Factory)? = ...): Lazy<TypeVariable(VM)> defined in androidx.activity
private val viewModel: MyViewModel by viewModels()
^
kotlin/com/example/app/MyApplication.kt:7:23: error: unresolved reference: Hilt_MyApplication
class MyApplication : Hilt_MyApplication()
^
Sep 30, 2022 12:18:56 AM worker request 0
SEVERE: Compilation failure: compile phase failed:Target //:exampleapp failed to build
INFO: Elapsed time: 50.154s, Critical Path: 26.76s
INFO: 633 processes: 36 internal, 533 darwin-sandbox, 64 worker.
FAILED: Build did NOT complete successfully
Circling back here - I looked into this issue some. From what I saw the plugins are in fact being picked up correctly. I haven't figured out why but I think there's something wrong with this particular plugin and Kapt that causes the annotation processors to not work correctly.
Any updates on this issue? I'm running into this error when I try to add exported_plugins
to kt_android_library
:
does not have mandatory providers: 'JavaPluginInfo'. Since this rule was created by the macro 'kt_android_library', the error might have been caused by the macro implementation
No immediate updates here at the moment, but I expect this to be resolved once we switch to the Starlark implementation of rules_android
.
I don't have a solution here, but digging into this more, this does appear to be resolved from the rules_kotlin side, and instead this stems from the annotation processor itself. An example application class like:
@HiltAndroidApp(Application::class)
class DemoApplication : Hilt_DemoApplication()
Results in the annotation processor (this line) seeing Object
as the application's superclass, rather than Hilt_DemoApplication
.
I've opened this as google/dagger#4075. I have a work-around I can share if people would like (it's linked in the Dagger issue), but it's a bit of a hack.