gradle无法使用annotationprocessor生成的源代码编译代码

1dkrff03  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(864)

如何使用annotationprocessor生成的源代码使gradle构建/编译项目?
我有一个有两个模块的项目
app annotation->是一个模块,它定义了一个注解和abstractprocessor的继承者
app api->包含带有上一模块注解的实体
其思想是为每个实体生成默认的crud存储库和服务,如果需要,还可以扩展一些服务。
问题是,它生成了所有需要的java文件(甚至intellij idea也可以看到这些文件),但是只要我想扩展其中一个服务,它就会在编译时失败,因为据我所知,在编译我的类时,并没有在编译之后生成的超类。如果我只重新编译我的类,那就没问题了,而且eclipse编译时完全没有错误,只有在我使用idea或gradlew构建时。
为了解决这个问题,我们使用了下面的解决方案,但是看起来不是很好

configurations {
    preProcessAnnotation
}

def defaultSrcDir = "$projectDir/src/main/java"
def entitySources = "$projectDir/src/main/java/com/abcd/app/entity"
def generatedSources = "$buildDir/generated/sources/annotationProcessor/java/main"
def generatedOutputDir = file("$generatedSources")

// Explicitly run the annotation processor against the entities
task preProcessAnnotation (type: JavaCompile) {

    source = entitySources
    classpath = sourceSets.main.compileClasspath
    destinationDirectory = generatedOutputDir
    options.sourcepath = sourceSets.main.java.getSourceDirectories()
    options.annotationProcessorPath = configurations.getByName("preProcessAnnotation") 

    options.compilerArgs << "-proc:only"    
    options.encoding = "ISO-8859-1"
}

// Explicitly specify the files to compile
compileJava {
    dependsOn(clean)
    dependsOn(preProcessAnnotation)

    def files = []
    fileTree(defaultSrcDir).visit { FileVisitDetails details -> 
        files << details.file.path 
    }
    fileTree(generatedSources).visit { FileVisitDetails details -> 
        files << details.file.path 
    }   
    source = files

    options.compilerArgs << "-Xlint:deprecation"
    options.compilerArgs << "-Xlint:unchecked"
    options.encoding = "ISO-8859-1"
}
....

dependencies {

    preProcessAnnotation project(':app-annotation')

    // Generate the crud repositories and services
    compile project(':app-annotation')
    implementation project(':app-annotation')
    ...
}

我只是好奇类似的代码生成框架如lombok、dagger2是如何毫无问题地工作的。
我觉得应该简单得多,不是吗?

6xfqseft

6xfqseft1#

正如您所意识到的,任何代码生成都必须在编译之前完成。
更干净的方法是将代码生成逻辑/注解作为依赖项。

task codeGen {
    // creates under build/genSrc
}

//add to default source set
sourceSets.main.java.srcDir "build/genSrc"

//this has access to all code
compile.dependsOn codeGen

相关问题