Warning: Dagger’s KSP support is currently in alpha.
Requirements
- Dagger
2.48
(or above) - Kotlin
1.9.0
(or above) - KSP
1.9.0-1.0.12
(or above)
Setup
Note: This guide focuses on Gradle. If you are using a different build system, please consult the documentation for that build system to enable KSP.
A general guide for migrating Gradle processors from KAPT to KSP can be found at https://developer.android.com/build/migrate-to-ksp.
The main steps are:
- Apply the Kotlin JVM plugin (or Kotlin Android plugin)
- Apply the KSP plugin.
- Change the compiler dependency configurations from
kapt
toksp
.
plugins {
// STEP 1: Apply the Kotlin JVM (or Kotlin Android plugin)
id "org.jetbrains.kotlin.jvm" version "1.9.0"
// STEP 2: Apply the KSP plugin
id "com.google.devtools.ksp" version "1.9.0-1.0.12"
}
// STEP 3: Change compiler dependencies from 'kapt' to 'ksp' configuration.
dependencies {
ksp "com.google.dagger:dagger-compiler:2.48" // Dagger compiler
ksp "com.google.dagger:hilt-compiler:2.48" // Hilt compiler
}
New Dagger SPI plugin (with KSP support)
Dagger’s KSP processor requires all registered Dagger SPI plugins to be converted to the new Dagger SPI plugin API. The new API provides wrappers around the Javac and KSP model types that allows users to write plugins that support both Javac and KSP. The full list of wrappers are shown below.
Dagger Wrapper | Javac | KSP |
---|---|---|
DaggerAnnotation | AnnotationMirror | KSAnnotation |
DaggerType | TypeMirror | KSType |
DaggerElement | Element | KSDeclaration |
DaggerTypeElement | TypeElement | KSClassDeclaration |
DaggerExecutableElement | ExecutableElement | KSFunctionDeclaration |
Users can get access to the underlying Javac or KSP type of a wrapper by calling
its #javac()
or #ksp()
methods, respectively. In addition, all wrappers have
a #backend()
method that can be used to switch logic based on the current
backend. For example:
/** Returns the qualified name of the given {@link DaggerTypeElement}. */
String getQualifiedName(DaggerTypeElement typeElement) {
switch (typeElement.backend()) {
case JAVAC: return typeElement.javac().getQualifiedName();
case KSP: return typeElement.ksp().getQualifiedName().asString();
default: throw AssertionError("Unexpected backend: " + typeElement.backend());
}
}
Note that calling #javac()
when processing with KSP (or calling #ksp()
when
processing with Javac) will throw an exception.
Interaction with Javac/KAPT processors
KSP processors are not able to resolve types generated by other Javac/KAPT processors. Thus, if your project contains other processors that generate classes that need to interact with Dagger or Hilt, then those processors also need to be migrated to KSP.
For example, if you’re using the androidx.hilt:hilt-compiler
, it should also
be migrated to use the ksp
configuration. KSP support for
androidx.hilt:hilt-compiler
is available in version
1.1.x.
Note that even if another processor is not directly related to Dagger/Hilt, it
will still need to be migrated to KSP if its generated type needs to be
inspected by the Dagger/Hilt processor. For example, consider the usage of an
AutoFactory generated class
within an @Inject
-annotated constructor:
@AutoFactory
class SomeClass(@Provided val dep: Dep, arg: String)
class Foo @Inject constructor(val factory: SomeClassFactory)
If com.google.auto.factory:auto-factory:1.0.1
is in the kapt
configuration,
then the generated class SomeClassFactory
will not be visible to the Dagger
processor while it inspects the parameters of the @Inject
constructor. For
such cases, an error similar to the following will be raised:
... was unable to process ‘Foo’ because 'SomeClassFactory' could not be resolved.
Even though usages of @AutoFactory
can be replaced with Dagger’s
@AssistedInject
APIs, there might be other processors that might prevent your
project from migrating to KSP’s version of Dagger.