在我的项目的源代码包下生成Java源代码

时间:2019-10-09 19:14:44

标签: annotation-processing javapoet annotation-processor

我有我的注释处理器:

public class MyAnnotationProcessor extends AbstractProcessor {
    ...

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // Here I deal with the annotated element
         ...

        // use JavaPoet to generate Java source file
        TypeSpec generatedClazz = generate_code();
        JavaFile javaFile = JavaFile.builder("com.my.foo", generatedClazz).build();
        javaFile.writeTo(filer);
    }

}

在上述process回调中处理带注释的元素之后,我使用JavaPoet生成Java源代码并为该代码创建Java文件。在构建我的项目时,除了默认情况下生成的Java源代码文件转到build/generated/sources/myApp/com/my/foo之外,其他所有东西都可以工作。如何使生成的Java文件位于项目的源代码位置src/main/java/com/my/foo中?

我的gradle版本:

plugins {
    id 'java'
}

group 'com.my.app'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {

    testImplementation 'junit:junit:4.12'

    implementation 'com.squareup:javapoet:1.11.1'
    implementation 'com.google.guava:guava:28.1-jre'
}

2 个答案:

答案 0 :(得分:0)

坏消息:注释处理器无法做到这一点-其回合工作方式的本质意味着,在“实际”源所在的同一目录中生成源就没有意义了,因为这些生成的源下次运行注释处理器时,它将被视为输入。

好消息:JavaPoet与您如何实际调用它无关,因此您只需编写一个简单的main()即可进行代码生成,并可以在构建时要求IDE对其进行调用,或将其附加到gradle建立。如果您打算在生成源之后手动对其进行编辑,则可能不希望发生这种情况,因为您可能希望保留手动更改,而不是每次构建时都将其覆盖。

JavaFile.writeTo(...)方法具有多个覆盖,并且其中只有一个覆盖注释处理器Filer。使用Filer有一些优点-很清楚您打算在哪里编写该类-但是JavaFile.writeTo(File directory)也应以这种方式使用。您不会将要传递MyClass.java的实际文件传递给它,而只是传递您要写入的源目录。在您的情况下,大约为javaFile.writeTo(new File("myProject/src/main/java"))

您可能仍然应该参数化如何调用该main,以便它知道使用哪些输入,如何理解您的现有资源等。另一方面,如果您的generate_code()不需要任何现有的源代码来自同一项目来运行,这应该很简单。

答案 1 :(得分:0)

不确定gradle,但是通过maven,您可以使用maven-compiler-plugin中的以下标签定义生成的源目录。

<generatedSourcesDirectory>
     ${project.basedir}/src/main/java
</generatedSourcesDirectory>

有关完整示例,请检查以下链接。

https://www.thetechnojournals.com/2019/12/annotation-processor-to-generate-dto.html