I'm using Dagger 2 and Kotlin for Android development.
My project is also a multi-module project.
My settings.gradle file is like this:
include :app
include :lib
I'm also maintaining the lib module.
In the Dagger Files (for example in the component), I try to get the item from other module. For example:
#Component
interface AppComponent{
fun getPresenter() : Presenter
}
The Presenter object is defined in lib module. I was working in linux environment and I'm using Android Studio 3 preview canary 5. The code is working well and I am able to generate APK.
But my company wanted to generate the APK using stable version of Android Studio. I'm using Android Studio 2.3.3.
When compiling the Android Project, I encountered this error:
error: error.NonExistentClass
The error appears when
:app:kaptDebugKotlin
is performed and caused by the dagger class cannot found, the class is defined in the other project. What can be the possible workaround for this? Sorry for my bad English.
Just add this to build gradle file to avoid the issues related NonExistentClass
kapt {
correctErrorTypes true
}
https://kotlinlang.org/docs/reference/kapt.html#non-existent-type-correction
The Root Cause
Basically, there's not much that can be done to fix this when using kapt. To quote this link that tackles the same problem in another library that uses pre-processors (OrmaDatabase):
Because Kotlin makes its stubs before Java Annotation Processing runs,
Kotlin knows just nothing about OrmaDatabase, and the name of the
declaration in stubs will be error.NonExistentClass. This breaks the
Annotation Processing tool. It's a kind of kapt limitation
How to fix it (the workaround)
Just use plain apt or annotationProcessor for running Dagger compiler. As soon as I changed:
kapt libs.daggerCompiler
to
annotationProcessor libs.daggerCompiler
in my module level build.gradle file, I was able to get the errors. After you've fixed the errors, you gotta revert the line back to kapt because otherwise dagger classes wouldn't be generated since they're defined in Kotlin.
I had a very similar situation with a NonExistentClass error in a multi-module project using Dagger and turns out I forgot to add the kotlin library dependency. So, just adding it in the sub-module solved my problem:
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$rootProject.kotlinVersion"
tldr: Change kapt to annotationProcessor in build.gradle and you will see the real problem.
I got the same error, and it turned out that I just commented out a class that I was using in my AppComponent. Unfortunately the kapt tool didn't give me the proper error message. If you change the kapt to annotationProcessor at your library's compiler, and try to build, it won't succeed neither, but you will get a more detailed error message.
In my case, I had #Nullable annotation from support-annotations while I had removed it in order to migrate to AndroidX.
When building, because the annotation was not imported correctly, it was detected as invalid.
What I did was to check the code and fix all imports.
After removing the outdated library
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
I got this error:
incompatible types: NonExistentClass cannot be converted to Annotation
Looking at https://dagger.dev/hilt/view-model.html I changed in a ViewModel:
class MainViewModel #ViewModelInject constructor(
...
) : ViewModel() {
to
#HiltViewModel
class MainViewModel #Inject constructor(
...
) : ViewModel() {
I've found if you're using
kapt {
generateStubs = true
}
changing to false will then present the actual error, you will probably have issues building the Dagger Graph once it's compilation issues have been corrected, but simply change back to true, and you should be good
It seems, there is a bug with kapt, project cleaning should help.
./gradlew clean
I got this error when I had moved by mistake a test class into my main sourceset. Moving it back to the test sourceset got rid of the error.
I received this error, when there was a compilation error in my Injected class. Please ensure that there aren't any compilation errors.
For all those arriving like me on this topic with a similar error.
Check your annotation imports.
For me the problem was I had the #MicronautTest annotation same as another test just the wrong one. Somehow intellij seems to think the import is fine while it really is not.
I had
import io.micronaut.test.extensions.junit5.annotation.MicronautTest
yet needed the kotest one.
import io.micronaut.test.extensions.kotest.annotation.MicronautTest
The kapt error is, while technically correct, quite uninformative.
So just check the imports and if they are all correct.
ERROR : error.NonExistentClass
This means there is a problem with providing dependencies( and not the dependency itself!).
Sometimes annotation processor(in this case Dagger) is unable to build dependency graph on the first build iteration due to a provider absence.
For instance: You are passing GlideApp as a parameter in your provider while GlideApp class is not generated yet! So, watch out for your providers for NonExistentClass errors.
I had the same issue recently. As I sometimes commit through the Android Studio (3.4.c6) I use the "Optimize imports" option to remove unused imports. For some reason, it removed the import for the Parcelize annotation.
It appeared the errors after I upgraded the .gradle version.
Upgraded the version for mockito from 2.7.21 to 2.+ fixed the issue for me.
- androidTestCompile "org.mockito:mockito-android:2.7.21" // remove this
+ androidTestCompile "org.mockito:mockito-android:2.+" // add this
If you come across this problem after Android X migration and start loosing your mind here is one thing you can try.
My Case:
Our project had few modules in it, lets call one of them myModuleProject.
After migration to Android X it was compiling and running fine if I run it from android studio, but when code moved to cloud and CI starts build, it was failing with ':myModuleProject:kaptDebugKotlin' and with long list of errors such as
e: /home/circleci/code/myModuleProject/build/tmp/kapt3/stubs/debug/package_name_here/reporter/bindingadapter/SomeBindingAdapterKt.java:14: error: incompatible types: NonExistentClass cannot be converted to Annotation
#error.NonExistentClass()
After two days of nightmare I found that not only root project gradle.properties but also module projects should include following!
android.databinding.enableV2=true
android.useAndroidX=true
android.enableJetifier=true
It seems kapt cannot find the class, or cannot determine which class to use. e.g.
import foo.* // class foo.Abc
import bar.* // annotation bar.Abc
#Abc
class Xyz { ... }
I had a project with Dagger injecting something into Presenters
At one moment I got a persistent
"NonExistentClass.java:3: error: error.NonExistentClass must be INTERFACE" error
The root cause was trivial: a rogue copy of the valid #Inject annotated file with unsatisfied dependencies somehow slipped into the project. How can we find it? The project in Android Studio looks OK.
Look at the error message, it looks like:
/home/alex/AndroidProvects/TopProject/app/build/tmp/kapt3/stubs/onlineDebug/error/NonExistentClass.java:3: error: error.NonExistentClass must be INTERFACE
public final class NonExistentClass {
Search at the compiled by kapt build files in
/home/alex/AndroidProvects/TopProject/app/build/tmp/kapt3/stubs/onlineDebug/app for "NonExistentClass" string
You will find the exact file with the exact unsatisfied Dagger dependency (in my case it was a rogue orphan file in the place where it shouldn't exist)
I had similar issues with dagger. Adding the following helped solve it :
// dagger
implementation dep('com.google.dagger:dagger')
implementation dep('com.google.dagger:dagger-android-support')
implementation dep('com.spotify.dagger.android:dagger')
kapt dep('com.google.dagger:dagger-android-processor')
kapt dep('com.google.dagger:dagger-compiler')
Related
Trying to integrate hilt using android Api Documentation but app crashed with following exception. https://developer.android.com/training/dependency-injection/hilt-android
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.package.application/com.package.application.MainActivity}:
java.lang.ClassCastException: com.package.application.DaggerAppApplication_HiltComponents_ApplicationC$ActivityRetainedCImpl$ActivityCImpl
cannot be cast to com.package.application.MainActivity_GeneratedInjector
What worked for me:
Removed the #AndroidEntryPoint annotation from the activity.
Ran the code and of course, it failed.
Had a fragment inside the activity. So, I deleted the fragment code as well.
Ran the code, it failed.
Added the #AndroidEntryPoint annotation to the activity again.
Ran the code. It ran and the error disappeared.
For me, as a dependency declaration inside my app build.gradle, i had to use api instead of implementation:
api project(':features:feedModule')
Learn more here: https://github.com/google/dagger/issues/2064
Update:
Dagger team released classpath aggregation feature which can resolve this issue. You can learn more here:
https://dagger.dev/hilt/gradle-setup#classpath-aggregation
Basically, in your app module build.gradle, you need to add:
hilt {
enableExperimentalClasspathAggregation = true
}
If your Android Gradle plugin version used in the project is less than 7.0, make sure to also add this to you build.gradle file:
android {
...
lintOptions {
checkReleaseBuilds false
}
In my case, I was getting a similar ClassCastException because the module where my #HiltAndroidApp app class was didn't have access to the module where my #AndroidEntryPoint activity was. Moving my App class to the app module (that has access to all the other Gradle modules) solved the problem.
From the docs:
Because Hilt's code generation needs access to all of the Gradle modules that use Hilt, the Gradle module that compiles your Application class also needs to have all of your Hilt modules and constructor-injected classes in its transitive dependencies.
Solved it by adding missing dependency for androidx hilt.
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
Other dependencies that I have in my gradle file.
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02"
implementation 'com.google.dagger:hilt-android:2.28-alpha'
kapt 'com.google.dagger:hilt-android-compiler:2.28-alpha'
implementation "androidx.fragment:fragment-ktx:1.2.5"
Plus fragment and its activity who are injecting viewmodel using hilt both are annotated as
#AndroidEntryPoint
I spent a couple of hours fixing this exact issue but solved it by doing Invalidate cache/restart + Rebuilding of all modules.
This is related to this issue from Hilt:
Hilt: More meaningful error messages
Dagger sometimes doesn't work well, even if the code is correct.
One possible solution is to rename the class to something else("Class2"), rerun the app, and check if it works. If it works, rename the class back to its original.
This is solved by invalidate cache and restart
I had the same problem and here are the steps I followed:
appModule starts with internal
In your app level build.gradle inside android section add the following line:
enableExperimentalClasspathAggregation = true
}
My dependencies are in this order:
classpath "com.google.dagger:hilt-android-gradle-plugin:2.40.5"
app-level build.gradle:
top plugin section
plugin{
...........
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
dependencies section
//dagger-hilt
implementation 'com.google.dagger:hilt-android:2.40.5'
kapt 'com.google.dagger:hilt-android-compiler:2.40.5'```
It is really silly solution but just comment out the injection annotation and injected fields, run the app then uncomment them and run again
It's also happened to me when I'm importing an .aar with "implementation".
(an .aar which includes hilt)
Like Sher Sanginov said instead of using "api" who increase compilation time, you can add the following lines in your build.gradle(app)
hilt {
enableAggregatingTask = true
}
enableExperimentalClasspathAggregation is now deprecated,
see https://dagger.dev/hilt/gradle-setup#aggregating-task
I was having the same java.lang.ClassCastException after adding Hilt.
Steps to fix the problem:
1. Build -> Clean Project
2. Build -> Rebuild Project
Also kapt doesn't work any more. Just add one plugin:
id 'dagger.hilt.android.plugin'
Then, add Hilt dependencies:
implementation "com.google.dagger:hilt-android:2.38.1"
annotationProcessor "com.google.dagger:hilt-compiler:2.38.1"
Steps need to perform:
Remove .gradle file in app's directory
Invalidate cache and restart android studio
Hopefully it will resolve your problem.
For me it was that I forgot to add #AndroidEntryPoint to a parent activity that was calling a second activity and this one calling the fragment. Obviously everyone of them need to have an #AndroidEntryPoint
You can delete you app's build folder as well as delete the gradle build cache on your system.
rm -rf app/build
rm -rf ~/.gradle/caches/build-cache-1
Deleting just the build cache is better than removing all the Android Studio cache.
In my case file does not contain the package, so hilt is not able to map the file and generate it in the generated folder. For that reason, hilt is not able to resolve the file.
I added the package in the fragment, and it resolve my issue
I added a new Retrofit interface to my project containing a couple of Endpoints annotated with the #GET and #HEADERS annotations, after Injecting said interface to a repository class using the #Inject annotation in the constructor of said class, Android Studio throws this error:
NonExistentClass cannot be converted to Annotation
After taking a look at the generated Java code, it replaces the #GET and #HEADERS annotations with this:
#error.NonExistentClass()
I've already tried the following:
Using annotatioProcessor instead of kapt
Setting jetifier.enabled to false in gradle.properties
Setting generateStubs to true in my build.gradle file
Setting correctErrorTypes to true in my build.gradle file
Im using:
Android Studio 3.3
Kotlin 1.3.11
Dagger 2.21
Retrofit 2.3.0
Kotlin
Kapt
could it be some dagger scope issue? or Retrofit / dagger not fully compatible with the new versions of the Kapt plugin?
Luckily this question led me to figure out my issue. While moving around classes from an app module into a library, I was referencing an annotation class which only existed in a debug folder. So debug builds were fine, but calls to gradlew install failed when generating release files.
The error for me was very explicit although it took me a long time to realize - the generated file had literally replaced the missing annotation with #error.NonExistentClass()
Moving the file into the main src set meant both debug and release builds could see the class. What took me a while to figure out was that I assumed this was a Dagger issue being masked by kapt, but really it was just a regular old Dagger issue. My advice is to look at your Dagger setup carefully.
For me, I had recently removed dagger from a project and forgot to remove the #Singleton and #Inject annotations from relevant classes.
For me, its painfully removing all the #Singleton and #OpenForTesting on my Module classes. And removing two DAO classes and Repository whose backing model classes is no longer annotated with #Entity.
For me was in here:
apply plugin: 'kotlin-android-extensions'
In my case I was using this ""com.fasterxml.jackson.core:jackson-databind:2.7.3" library, but later I removed this dependency from gradle, but didn't remove the code that I was using of this library, so removed code and annotations related to this library solved my problem.
Just had a similar problem: I was trying to use picocli's #Command annotation and was getting the same error. It turned out to be an issue with my imports. I was importing this and other annotations via a wildcard import: import picocli.CommandLine.*. When i replaced it with separate imports for each annotation (among which was import picocli.CommandLine.Command), kapt began working correctly.
I assume kapt simply doesn't understand wildcard imports.
For me the problem was caused by migration to view binding from kotlin-android-extensions and Android Studio couldn't find #Parcelize annotation. To add annotations back add this to build.gradle:
apply plugin: 'kotlin-parcelize'
I was using okhttp 3.8 with dagger 2.11, it works great. When I changed to okhttp 3.9 I was getting ERROR javax.annotation.Nullable not found.
So by some luck I tried including the dagger-android2.x dependency and that fixed the error.
I understood that If you want to use classes like DaggerActivity or if you want to inject activities or fragments you must include the dagger.android package, but why do I need to include it for OkHttp to be used with Dagger?
Edit: I did some more investigating.
This change in the https://github.com/square/okhttp/commit/d4a9cf4772ae9d8991e58d934dea433798c9b8eb#diff-e88e53bd5c3b6fb1ba650f55b1261052R21
+import javax.annotation.Nullable;
is the problem.I had to include:
implementation 'com.google.code.findbugs:jsr305:3.0.2' to fix the error
Update 2:
I was injecting into my websocket listener, which I really didn't need to do. This caused the ERROR javax.annotation.Nullable not found. I changed my code to not inject into the websocketlistener and the error is gone and no need for additional dependencies, the error was entirely my fault.
You don't actually have to include the dagger-android2.x dependency. What happens is that OkHttp 3.9 now uses the javax.annotation.Nullable, which the dagger-android2.x dependency uses internally and is, therefore, also available for OkHttp through gradle merge.
Adding compile 'com.google.code.findbugs:jsr305:3.0.2' to your project should be enough, as you pointed out.
I updated Android Studio from 2.x to 3.x last week end. The project migration was perfect, build was great. And now, from 2 hours, I can't explain why, I can't build, I have this error on Glide now:
Error:(26, 22) error: cannot find symbol class GlideApp
All was good before, I didn't change anything (gradle or configuration), and now this error appears...
For information about Glide, in my Gradle:
annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0-RC1'
compile 'com.github.bumptech.glide:glide:4.0.0-RC1'
compile 'com.github.bumptech.glide:okhttp3-integration:4.0.0-RC1'
The GlideApp file is generated automatically (I checked it).
So, it's a crazy situation. Thank you very much guys!
Some of these situations tend to pop up from time to time (for an instance with the generated class R, where it ends up not being generated). The easiest way I have solved this in the past is to clean the project and rebuild it. And if that doesn't work, press File in the top menu and press "Invalidate caches and restart". A second popup will appear, press "Invalidate caches and restart". It may take a while as Android Studio needs to re-index and rebuild the project, but it solves most issues I have had.
The same happened to me and it was one of weirdest errors I ever got,
I used Butterknife in my project and I found out that if you define the views in private mode, you get this error
use:
#BindView(R.id.tv_option_one)
TextView tv_option_one;
#BindView(R.id.tv_option_two)
TextView tv_option_two;
instead of
#BindView(R.id.tv_option_one)
private TextView tv_option_one;
#BindView(R.id.tv_option_two)
private TextView tv_option_two;
it mostly happens when Butterknife can't find the view when you use bindView or the onClick annotation, and the worst part is that it shows errors everywhere except the place where they should be.
I ran into the same problem when I migrated to AndroidX. I ended up solving it by adding/updating the dependencies to
implementation 'com.github.bumptech.glide:glide:4.8.0-SNAPSHOT'
kapt 'com.github.bumptech.glide:compiler:4.8.0-SNAPSHOT'
kapt 'androidx.annotation:annotation:1.0.0-rc01'
This also happens when you have another error in your code. Gradle doesn't get to generate Glide classes since another error is thrown before it
Glide 4.x introduces some breaking changes. Be sure to follow the instructions in the Download & Setup page of Glide docs.
Do not neglect the changes in proguard.cfg. After changes, rebuild your project and you should be able to access GlideApp.
add those dependencies like so
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
In my case, I forgot to apply kapt plugin, So I just added it to my module-level build.gradle.
apply plugin: 'kotlin-kapt'
You can find more details about it - Glide Docs
I have picked up this problem when a sub-package uses GlideApp with AppGlideModule being extended in a class one level up in the package hierarchy.
I suspect that the compiler tries to compile the sub-package classes before generating GlipeApp.
My solution was to extend AppGlideModule in a separate module and then add it as a dependency to all the modules using GlideApp.
If you are using DI, you could try comment out GlideApp error code, then rebuild. IDE should you where the error truly is.
I got the solution of this issue.
Build -> Clean project (After) Rebuild Project
Then after you will able to import the GlideApp in your project
For Reference
https://github.com/bumptech/glide/issues/1945
For me, the problem was that there was a different import error (which was a "valid" error, I had indeed deleted the referenced method).
But because I got like 20 messages that GlideApp can't be found when building the app, I didn't even notice that there was such an error.
After correcting that error and rebuilding the project, everything worked normally again.
Generation of the following class worked for me:
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
#GlideModule
public final class MyAppGlideModule extends AppGlideModule {
// Dummy. Needed to generate GlideApp. See:
// GlideApp.with(service).
}
In our Android app we're using DBFlow to access the SQLite database. We're referencing the classes generated by DBFlow via Kotlin. We are already aware of the fact that we have the model classes as well as the database class in Java as code generation won't work when writing these classes in Kotlin.
However we still have to build the code twice after every project clean. Executing the first build on a device results in ClassNotFoundExceptions for seemingly random Kotlin classes (even if they don't access code generated by DBFlow or any of the model classes defined by us). The same is reported already at compile time when enabling Proguard which of course fails the build. The second build always succeeds.
The funny thing is, that code generation already works at the first run - the classes are there and are also picked up by the IDE. But the compiler somehow can't find them making me think that the code generation happens too late in the build process. On the other hand as explained above there are also classes not found which don't have to do anything with code generation and/or annotation processing.
So is there a better solution to this problem than a second build?
For reference, the relevant parts of our app's build.gradle looks like this - just like the DBFlow documentation is suggesting:
def dbflow_version = "3.0.0-beta4"
dependencies {
kapt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}"
compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}"
}
kapt {
generateStubs = true
}
Edit: I found that I also have to rebuild twice for every change I make to the code. It compiles correctly in the first build if I didn't clean before, but the changes simply aren't picked up.
If you use kotlin and retrolambda this might fix it:
me.tatarka:gradle-retrolambda:3.4.0
github gist