【问题标题】:Java annotation processing with JavaPoet - Attempt to recreate a file for type使用 JavaPoet 处理 Java 注释 - 尝试为类型重新创建文件
【发布时间】:2021-06-09 14:08:25
【问题描述】:

我正在使用带有JavaPoet 的java 注释处理API 来生成文件和maven 来编译我的项目。

它按预期工作,结果文件在/target/generated-sources/annotations/sk/typek/generated/TestGeneratedClass.java下生成。

但是,任何后续的mvn compile 都会失败并显示Caused by: javax.annotation.processing.FilerException: Attempt to recreate a file for type sk.typek.generated.TestGeneratedClass

我知道我可以在每次重新编译之前调用mvn clean(然后它再次工作),但我不想这样做。我之前使用的其他注释处理库没有这个问题,所以他们以某种方式处理了它。

如果生成的文件已经存在,有没有办法“强制覆盖”?或者是否可以删除旧生成的文件(如果存在)作为我的注释处理代码的一部分?

我搜索了解决方案,但找不到任何有用的东西。

我的注释处理器如下所示:

package sk.typek.annotation;

import com.google.auto.service.AutoService;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;

@SupportedAnnotationTypes("sk.typek.annotation.TestAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@AutoService(Processor.class)
public class TestAnnotationProcessor extends AbstractProcessor {
    private Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        this.filer = processingEnv.getFiler();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
        if (annotations.isEmpty()) {
            return false;
        }
        System.out.println("Processing annotations: " + annotations);
        try {

            TypeSpec.Builder classBuilder = TypeSpec.classBuilder("TestGeneratedClass")
                    .addModifiers(Modifier.PUBLIC, Modifier.FINAL);

            JavaFile javaFile = JavaFile.builder("sk.typek.generated", classBuilder.build())
                    .build();
            System.out.println("Writing file TestAnnotation to package " + javaFile.packageName);
            // tried this doesnt work
            if (javaFile.toJavaFileObject().delete()) {
                System.out.println("Deleted previously generated file");
            }
            javaFile.writeTo(filer);
        } catch (IOException e) {
            throw new DiffBuilderAnnotationProcessorException(e);
        }
        return true;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return Collections.singleton(TestAnnotation.class.getCanonicalName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}

【问题讨论】:

    标签: java annotation-processing javapoet


    【解决方案1】:

    查看您的代码,很清楚您收到错误消息的原因。每次mvn compile 完成时,处理器都会创建一个文件——即使是处理器也不需要。

    如果需要重新创建文件,您需要询问处理器。您可以通过向处理器询问要创建的元素列表来做到这一点:

    roundEnv.getElementsAnnotatedWith(TestAnnotation.class))
    

    这将返回带有 TestAnnotation 注释的元素列表,这些元素自上次编译以来已更改/需要构建。在mvn clean 之后,列表将包含所有元素。

    将您的代码更改为:

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
        if (annotations.isEmpty()) {
            return false;
        }
        System.out.println("Processing annotations: " + annotations);
        for (Element element : roundEnv.getElementsAnnotatedWith(TestAnnotation.class)) {
            try {
                TypeSpec.Builder classBuilder = TypeSpec.classBuilder("TestGeneratedClass")
                        .addModifiers(Modifier.PUBLIC, Modifier.FINAL);
    
                JavaFile javaFile = JavaFile.builder("sk.typek.generated", classBuilder.build())
                        .build();
                System.out.println("Writing file TestAnnotation to package " + javaFile.packageName);
                // tried this doesnt work
                if (javaFile.toJavaFileObject().delete()) {
                    System.out.println("Deleted previously generated file");
                }
                javaFile.writeTo(filer);
            } catch (IOException e) {
                throw new DiffBuilderAnnotationProcessorException(e);
            }
        }
        return true;
    }
    

    应该避开这个消息。

    【讨论】:

      猜你喜欢
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 2015-11-18
      • 2020-10-24
      • 2017-05-22
      • 2017-01-05
      相关资源
      最近更新 更多