添加sourceSet时已设置endPosTable

Nic*_*ico 4 java eclipse preprocessor gradle

我正在使用自定义注释处理器并遇到一个新问题.我正在使用Gradle(3.1.1),当我将处理器生成的文件路径添加到sourceSet时,我会遇到奇怪的问题.

gradle clean build然后我执行了一个gradle build后来的构建得到了摧毁.我得到的堆栈跟踪是一个非常常见的令我惊讶的.

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)
Run Code Online (Sandbox Code Playgroud)

如果我在构建之前总是清理我没有问题,那么当我不添加sourceSet时,构建总是成功的.我甚至尝试在我的注释处理器中创建新生成的文件之前删除该文件,但这也没有做到.

在研究的同时我也发现了这个有趣的链接: JDK Bug报告

但是考虑到我要么总是要先清理,要么将它从我的sourceSet中删除,这并不是很好.因为Eclipse不喜欢找不到符合惯例的文件.

您对如何解决这个问题有什么建议吗?

Nic*_*ico 9

由于这是JDK 8的官方Bug,旨在在JDK 9中解决,我实现了一个解决方法,如果已经存在,则使用gradle删除该文件.处理器不再有问题,我可以将它保存在我的sourceSet中.

问候 :)

编辑:解决方法本身.

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 }
}
Run Code Online (Sandbox Code Playgroud)

我们使用gradle,因此这是gradle脚本的变通方法.但基本上解决方法是删除在开始编译和预编译步骤之前生成的文件.


Vla*_*nko 7

我正在尝试在我的Android应用程序的测试源集中使用生成的Dagger*文件.我在@Nico的解决方法中改变了一些事情,现在一切都对我有用.

/build.gradle:

ext {
    generatedSourcesDir = 'build/generated/source/apt/test/debug'
}
Run Code Online (Sandbox Code Playgroud)

/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 {
    ...
}
Run Code Online (Sandbox Code Playgroud)