Dagger 2.21+ unable to generate UnitTest Component in android - android

Let's start with an issue:
> Task :app:kaptAppDebugUnitTestKotlin FAILED
/app/build/tmp/kapt3/stubs/appDebugUnitTest/com/pckg/TestAppComponent.java:77: error: [ComponentProcessor:MiscError] dagger.internal.codegen.ComponentProcessor was unable to process this class because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
public abstract class TestAppComponent extends com.pckg.AppComponent {
^warning: The following options were not recognized by any processor: '[room.schemaLocation, kapt.kotlin.generated, room.incremental]'[WARN] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: android.databinding.annotationprocessor.ProcessDataBinding (DYNAMIC).
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:kaptAppDebugUnitTestKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
I'm trying to update our huge project to run with incremental kapt. One of the essentials was to update dagger. I tried a lot version, but the last one working is 2.20, everything above gives the mentioned 'error'.
To be honest, I don't see any error. The build works fine, when I assemble only app, but when I try to run the UnitTest task, it shows me that error. But I'm unable to find any issue, nor the AS code inspections in AppComponent. The TestAppComponent is not even generated.
I believe, we use completely regular setup of local unit tests for android.
Setup:
/core/src/main/com/pckg/core/Provisions.kt
interface Provisions {
....
}
/app/src/main/com/pckg/AppComponent.kt
#Component(modules=[....])
#Singleton
interface AppComponent : Provisions {
....
}
/app/src/test/com/pckg/TestAppComponent.kt
#Component(modules=[....])
#Singleton
interface TestAppComponent : AppComponent {
....
}
I also tried to make the Components to be abstract classes instead of interface (because the error says that class extends the interface, but without luck - same issue, just with abstract classes).
Of course I did try to run with --stacktrace, but it's just longer pointless exception.
Questions:
Do you know what needs to be changed when updating to dagger 2.21 and
above?
Do you know how to force dagger/kapt/gradle to say more than
(no error message)?
PS: Whatever library version you might think of is the latest. AGP 3.5.0, Gradle 5.5.1, Kotlin 1.2.50,...

I remember seeing something like this when I was trying to add the test component to the android tests. After adding the following to build.gradle the component was generated (originally I only had dagger in the kapt directive):
kaptAndroidTest "com.google.dagger:dagger-android-processor:$dagger_version"
kaptAndroidTest "com.google.dagger:dagger-compiler:$dagger_version"
If you're doing that for unit tests, adjust accordingly.
Note: If you're only seeing it when using incremental processing, then maybe it's some other configuration option you need to enable specifically for the unit test?

Turns out, the problem was in missing dependencies in tests.
In our case it was due to conflict with FindBugs.
We have defined FB as:
compileOnly "com.google.code.findbugs:annotations:3.0.1"
compileOnly "com.google.code.findbugs:jsr305:3.0.2"
So if we have a class with suppress:
public class JavaClass {
#Inject
#SuppressFBWarnings(value = "THIS_CRASHES_DAGGER",
justification = "Since this annotation is not available in test classpath, dagger will fail.")
Context mInjectedContext;
}
The #SuppressFBWarnings is not available in tests. This was ok up to dagger 2.20. But every version after is failing on that, because the annotation cannot be resolved. And dagger is trying to read other annotations to report you badly used annotations, etc.
The fix is easy:
testCompileOnly "com.google.code.findbugs:annotations:3.0.1"
testCompileOnly "com.google.code.findbugs:jsr305:3.0.2"
or making it implementation might ensure propagation to the tests also.
You can find more about this here: https://github.com/google/dagger/issues/1599

Related

Dagger "cannot access SomeComponent" during build

I started a new project using Dagger 2. The module structure is as following (→ meaning depends on with implement):
app → data → network
Each module has it's own Dagger component (e.g. AppComponent, DataComponent and NetworkComponent).
#Component(modules=[...])
interface NetworkComponent
#Component(dependencies=[NetworkComponent::class], modules=[...])
interface DataComponent
#Component(dependencies=[DataComponent::class], modules=[...])
interface AppComponent
The idea behind this setup is that the app module has no access to network but only knows data. The real structure is more complicated but this is the main principle.
While Android Studio is very happy with this setup, gradle won't compile it.
The error is:
> Task :app:kaptReleaseKotlin FAILED
error: cannot access NetworkComponent
class file for com.somepackage.network.di.NetworkComponent not found
* What went wrong:
Execution failed for task ':app:kaptReleaseKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
So while compiling the app module it fails to resolve the class it has no access to, but this class is nowhere referenced in the source of the app module. Dagger seems to internally trying to access it.
If I add a depency app → network the app compiles and runs fine.
Any idea how to solve this WHILE keeping app from accessing network? This separation is quite important for us.

Kapt annotation processing - how to show full stacktrace

I am working on a android project using Kotlin, Databinding and Room.
Sometimes the build fails with a error message, containing no information about what exactly went wrong, except that it has something to do with the annotation processor (which can have many causes...).
shortened Example:
org.gradle.workers.internal.DefaultWorkerExecutor$WorkExecutionException: A failure occurred while executing org.jetbrains
[more stack trace lines]
Caused by: org.jetbrains.kotlin.kapt3.base.util.KaptBaseError: Error while annotation processing
[even more stack trace lines]
at org.jetbrains.kotlin.kapt3.base.Kapt.kapt(Kapt.kt:45)
... 32 more
Finding the cause, then means time consuming backtracking of my steps (and maybe using git stash) and guessing, when one the 32 hidden lines at the end seems likely to contain some useful information about what actually went wrong.
So the question is: how to show the full stack trace?
I tried setting the -Xmaxerrs 500 in my build.gradle as shown here https://kotlinlang.org/docs/reference/kapt.html#java-compiler-options as well as various variants of this, I found on SE (sorry, don't remember which exactly).
None made any difference. Maybe i put the block in the wrong part? (tried module level, android -> defaultConfig -> kapt)
Add kapt.verbose=true to your project's gradle.properties file.
In my case, the issue was apparently with the 'suspend' keyword added to my Dao function. I may be missing dependency or there may be some dependency issue.
For example I changed the following:
#Query("select * from election_table")
**suspend** fun getAllElections():LiveData<List<Election>>
to
#Query("select * from election_table")
fun getAllElections():LiveData<List<Election>>
Room version: = "2.2.5"
Update: Yep - the issue is ensure you have the following dependencies:
//Room
implementation "androidx.room:room-runtime:$version_room"
kapt "androidx.room:room-compiler:$version_room"
implementation "androidx.room:room-ktx:$version_room"
I was missing the last one. Added suspend keyword again, and now compiles like a charm!

Dokka failure: com.intellij.psi.impl.source.PsiClassImpl cannot be cast to com.intellij.psi.PsiJavaFile

I have a build that generates Android artefacts (mainly an .aar) and bundles in dokka-generated docs (codebase is Kotlin+Java).
With some recent changes dokka started failing with this cryptic error:
> Task :mylib:dokka FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':mylib:dokka'.
> com.intellij.psi.impl.source.PsiClassImpl cannot be cast to com.intellij.psi.PsiJavaFile
Any help would be appreciated. I currently cannot seem to trace the source of this.
I can't pin-point the root of the problem but I can say for sure that Dokka has some issues with annotation classes.
In my changes, I had initially introduced a new annotation class based on Android's #IntDef inside an abstract class (alongside associated helper methods), written in Java.
These 2 steps seemed to have helped:
Switching to Kotlin for the annotation class' implementation, then defining the annotation class at a file's root scope (rather than as an inner item of a class).
Suppressing the annotation's package in Dokka's config, i.e. -
dokka {
...
packageOptions {
prefix = "com.mylib.myannotation"
suppress = true
}
}
The end result is that the documentation cannot reference the annotated class (that's no surprise, as it was suppressed), but the javadoc generation fully succeeded.

Custom Task in Gradle (Android)

(gradle newbie question)
I am looking to run a custom task with code from this thread. This is to do with setting up build env for release/debug etc...
Since the code bloats the original boilerplate code, I would like to do following for readability and extensibility -
Move the code to separate file as a task/def(Gist of the Code
Run the task/def before assembleDebug/Release
Here are problems I face when task is appended at the end of build.gradle file:
a) If I run just the task ./gradlew buildCustom , I get error
Could not find method defaultConfig() for arguments
b) If I try to use doLast I get error
Could not find method doLast() for arguments [task ':app:assembleDebug'] on task ':app:buildCustom'.
There is something very obvious that I donot understand, appreciate any help.

Dagger + ButterKnife = Could not initialize class dagger.internal.codegen.ModuleAdapterProcessor

I have a project where I'm using ButterKnife for view injection, and I just added dagger but I'm getting the following error:
Description Resource Path Location Type Internal compiler error:
java.lang.NoClassDefFoundError: Could not initialize class
dagger.internal.codegen.ModuleAdapterProcessor at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method) R.java /Suggest/gen/com/google/android/gms line 0 Java Problem
I'm using eclipse and I have the following in my Annotation config:
notice: I have written one #module with its #provides ... correctly, then removed it and still I'm having the same compilation error
I followed this comment to setup Annotation processing:
https://github.com/square/dagger/issues/126#issuecomment-11992320
I'm not sure if it's code-related or dependency and versions related, I just need someone to point me to the possibilities behind this error
For those looking for a solution, I just found out that using JavaWriter 2.1.1 Fixed the problem

Categories

Resources