sergei-lapin / napt

Alternative to KAPT that skips Java stub generation and therefore is as efficient as Java APT but with Kotlin
MIT License
88 stars 6 forks source link

Room + napt = javax.annotation.processing.FilerException: Attempt to recreate a file for type #14

Closed bacecek closed 1 year ago

bacecek commented 1 year ago

Hi! I have applied your plugin in module with Room and got the next issue:

Preparations: Let's assume we have module with build.gradle like this:

plugins {
    id 'com.android.application'
    id 'com.sergei-lapin.napt'
}

dependencies {
    annotationProcessor 'androidx.room:room-compiler:2.4.3'
    implementation 'androidx.room:room-runtime:2.4.3'
}

And we have the sample project from tutorial: https://developer.android.com/training/data-storage/room#java.

Steps:

  1. Successful compilation of module
  2. Make some changes to any source file
  3. Recompile the module

Result:

* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> javax.annotation.processing.FilerException: Attempt to recreate a file for type app.bacecek.defaultassistant.UserDao_Impl

This build fail is not reproducing without napt plugin.

Simple example is here: https://github.com/bacecek/sample-checking-assistant-role/tree/room_FilerException.

Environment: Napt version 1.17, JDK 11, Gradle 7.5.1, Android Gradle Plugin 7.2.1, Room 2.4.3.

I'n not sure that the main cause of this problem is this plugin so it would be great if you will help me to investigate what is the main cause and maybe to fill the issue in Google's issue tracker.

bacecek commented 1 year ago

I'm seeing that during incremental compilation before starting annotation processing URLClassLoader.getURLs() contains not only compiled kotlin classes, but also previous compiled java classes:

ClassLoader.getURLs: [file:/Users/bacecek/work/sample-checking-assistant-role/app/build/tmp/kotlin-classes/debug/, file:/Users/bacecek/work/sample-checking-assistant-role/app/build/intermediates/javac/debug/classes/]

And @Dao annotation has CLASS retention, so that annotation processor is trying to process UserDao class twice: as java source and as class file.

From my perspective, we can try to not add classes to Arguments.instance(context).getClassNames() that already exists in Arguments.instance(context).getFileObjects(). What do you think?

UPD: This is not so easy as I expected. Maybe you have any ideas how to fix it?

sergei-lapin commented 1 year ago

Hey, @bacecek! Seems like targeting KotlinCompile destinationDirectory directly does the trick and fixes this incremental scenario.

sergei-lapin commented 1 year ago

I'll prepare new release shortly

bacecek commented 1 year ago

Great, thank you! Now it works