-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
I am working on a project (dagger-grpc) which provides a different approach to dagger binding, with a focus on direct examples of integration with microservice containers (armeria in particular). I am building out the examples, and running into a difficulty wherein Dagger, when run as a KSP processor, blows up with an IllegalAccessException from a module violation, in attempting to reference a class in com.google.common.graph from another which has already been loaded in the outer container. (see trace below).
I referenced this in this comment
Environment:
- bazel_dep(name = "rules_kotlin", version = "2.1.0", repo_name = "io_bazel_rules_kotlin")
- Bazel 8.1.1
- OS: Mac/OS 15.3.1
- Dagger 2.55 (via maven_install / rules_jvm_external)
All bazel-isms are set up locally for the project, and use maven-downloaded deps. Notably, I set up a plugin declaration for dagger-compiler like so in my root BUILD.bazel file:
load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_ksp_plugin")
kt_ksp_plugin(
name = "dagger-compiler",
processor_class = "dagger.internal.codegen.ComponentProcessor",
visibility = ["//visibility:public"],
deps = [
"@maven//:com_google_dagger_dagger_compiler",
],
)
And then my target is like so:
kt_jvm_library(
name = "lib",
srcs = glob(["src/main/kotlin/**/*.kt"]),
plugins = [
"@dagger-grpc//io_grpc/compiler/ksp:plugin",
"//:dagger-compiler",
],
visibility = ["//visibility:public"],
runtime_deps = [
"@maven//:org_slf4j_slf4j_jdk14",
],
deps = [
"//proto:grpc",
"@com_google_protobuf//java/core",
"@dagger-grpc//api",
"@dagger-grpc//third_party/dagger", # Use your own dagger mapping in your repo
"@dagger-grpc//util/armeria",
"@maven//:com_google_guava_guava",
"@maven//:com_linecorp_armeria_armeria_grpc",
"@maven//:io_github_oshai_kotlin_logging_jvm",
"@maven//:io_grpc_grpc_protobuf_lite",
],
)
Expected behavior
Normal generation of dagger factories and component implementations.
Actual Outcome
Stack trace:
exception: java.lang.IllegalAccessError: failed to access class com.google.common.graph.BaseGraph from class com.google.common.graph.Traverser (com.google.common.graph.BaseGraph is in unnamed module of loader org.jetbrains.kotlin.preloading.MemoryBasedClassLoader @50b494a6; com.google.common.graph.Traverser is in unnamed module of loader java.net.URLClassLoader @268e3a1d)
at com.google.common.graph.Traverser.forTree(Traverser.java:182)
at dagger.internal.codegen.validation.ValidationReport.<clinit>(ValidationReport.java:43)
at dagger.internal.codegen.validation.InjectValidator$InternalValidator.validateUncached(InjectValidator.java:159)
at dagger.internal.codegen.base.Util.reentrantComputeIfAbsent(Util.java:33)
at dagger.internal.codegen.validation.InjectValidator$InternalValidator.validate(InjectValidator.java:155)
at dagger.internal.codegen.validation.InjectValidator.validate(InjectValidator.java:113)
at dagger.internal.codegen.validation.InjectBindingRegistryImpl.tryRegisterConstructor(InjectBindingRegistryImpl.java:257)
at dagger.internal.codegen.validation.InjectBindingRegistryImpl.tryRegisterInjectConstructor(InjectBindingRegistryImpl.java:243)
at dagger.internal.codegen.processingstep.InjectProcessingStep.process(InjectProcessingStep.java:73)
at dagger.internal.codegen.processingstep.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:94)
at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:297)
at dagger.internal.codegen.processingstep.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:72)
at dagger.internal.codegen.processingstep.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:49)
at dagger.spi.internal.shaded.androidx.room.compiler.processing.XProcessingStep.process(XProcessingStep.kt:57)
at dagger.spi.internal.shaded.androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at dagger.spi.internal.shaded.androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
...
Note: The presence of the other ksp plugin is immaterial - the issue reproduces irrespective of other plugins being present.
Reproduction Steps
I built a repro PR at geekinasuit/dagger-grpc#8
Analysis
The KSP environment provided by rules_kotlin is insufficiently isolated in its classloading. Something inside the ksp infrastructure itself uses parts of com.google.common.graph, but does not load all of it. Some provisional attempts to do a low-hanging-fruit fix on that end have failed (e.g. bazelbuild/rules_kotlin#1284).
Regardless of isolation on the containing end, dagger currently seems to be leaning into com.google.common.graph from within its own validation code (ValidationReport.java:43 based on the stack trace). This suggests com.google.common.graph is not "shaded" in the compiler maven artifact, leaving it exposed to collision with other usages of Guava in the containing environment. One fix of this, for Dagger, at least, would be to ensure that com.google.common.graph is package-rewritten to avoid the collision and class-loading module conflict. That was always best-practice for annotation processors anyway, back when I was involved with the project, but it may have changed since.