endPosTable already set when adding sourceSet

4.9k views Asked by At

I am using a custom annotation processor and have a new problem. I am using Gradle (3.1.1) and when I add the path of the file that will be generated, by my processor, to the sourceSet I get weird problems.

I perform a gradle clean build then a gradle build afterwards and the build get's destroyed. The stacktrace I get is a pretty common one to my surprise.

An exception has occurred in the compiler (1.8.0_91). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.IllegalStateException: endPosTable already set
    at com.sun.tools.javac.util.DiagnosticSource.setEndPosTable(DiagnosticSource.java:136)
    at com.sun.tools.javac.util.Log.setEndPosTable(Log.java:350)
    at com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:667)
    at com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:950)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.<init>(JavacProcessingEnvironment.java:892)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.next(JavacProcessingEnvironment.java:921)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1187)
    at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
    at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
    at com.sun.tools.javac.main.Main.compile(Main.java:523)
    at com.sun.tools.javac.main.Main.compile(Main.java:381)
    at com.sun.tools.javac.main.Main.compile(Main.java:370)
    at com.sun.tools.javac.main.Main.compile(Main.java:361)
    at com.sun.tools.javac.Main.compile(Main.java:56)
    at com.sun.tools.javac.Main.main(Main.java:42)

If I always clean before building I don't have a problem, alsothe build is always successfull when I don't add the sourceSet. I even tried deleting the file right before creating the new generated file in my annotation processor but that didn't do the trick either.

While researching I also found this interesting link: JDK Bug report

But thinking about that I either have to always clean first or to leave it out of my sourceSet is not really good. Since Eclipse doesn't like not finding a file that should be there by convention.

Do you have any suggestions on how to solve this?

2

There are 2 answers

0
Nico On BEST ANSWER

Since this is an official Bug of JDK 8 which is aimed to be resolved at JDK 9, I implemented a workaround with deleting the file with gradle if it already exists. The processor doesn't have a problem then anymore and I can keep it in my sourceSet.

Greetings :)

EDIT: The workaround itself.

gradle.ext.generatedQueriesDir = 'build/generated-sources/local/query'
/*
 * This is a workaround to delete the file that will be created by the annotation processor if it already exists.
 * There is a known bug in the Java compiler and JDK 8 which should be fixed at JDK 9.
 * http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8067747 <-- Master report
 * http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8146348 <-- duplicates master report
 */
if ( file( gradle.ext.generatedQueriesDir ).exists() ) {
  FileCollection collection = files { file( gradle.ext.generatedQueriesDir ).listFiles() }
  collection.each { delete it }
}

We use gradle so this is a workaround for a gradle script. But basically the workaround means to delete the file that will be generated before starting the compile AND pre-compile steps.

2
Vladimir Kondenko On

I'm trying to use generated Dagger* files in the testing source set of my Android application. I changed a couple of things in @Nico's workaround, now everything is working great for me.

/build.gradle:

ext {
    generatedSourcesDir = 'build/generated/source/apt/test/debug'
}

/app/build.gradle

android {
    sourceSets {
        test.java.srcDirs += generatedSourcesDir
    }
}

tasks.withType(JavaCompile) {
   if (file(generatedSourcesDir).exists()) {
       FileCollection collection = files { file(generatedSourcesDir).listFiles() }
       collection.each { delete it }
   }
}

dependencies {
    ...
}