繁体   English   中英

如何在 Java 注释处理器中获取正确的 JavaFileManager?

[英]How to obtain the right JavaFileManager in a Java annotation processor?

我通过扩展在 Eclipse 上下文中调用的javax.annotation.processing.AbstractProcessor编写了一个 Java 注释处理器,它工作正常,除了我需要有关源路径和类路径的更多信息才能使处理器工作:

@SupportedAnnotationTypes({"MyAnno"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class Processor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // this used to work in Java4 but not anymore (since Java6?):
        String sourcePath = processingEnv.getOptions().get("sourcepath");
        String classPath = processingEnv.getOptions().get("classpath");

        for (Element e : roundEnv.getElementsAnnotatedWith(MyAnno.class)) {
            myProcess(e, sourcePath, classPath); 
        }

        return true;
    }
}

问题是如何在注释处理上下文( process的实现)中检索一个有效的JavaFileManager ,它可以为我提供当前正在执行注释处理器的编译器的源路径和类路径。 最好,我会找到一个解决方案,它不涉及对 Eclipse/JDT 特定接口的依赖。

我试过工作的情况如下:

DiagnosticCollector<JavaFileObject> diagnostics =
                   new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(diagnostics, null, null);
fm.getLocation(StandardLocation.CLASS_PATH); // prints an empty class path

对于 Java 8 及之前版本:

import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Context;
import javax.annotation.processing.ProcessingEnvironment;

    protected static JavaFileManager getJavaFileManager(ProcessingEnvironment env) {
        JavaFileManager fm = null;

        if (env instanceof JavacProcessingEnvironment) {
            Context context = ((JavacProcessingEnvironment) env).getContext();

            fm = context.get(JavaFileManager.class);
        }

        return fm;
    }

对于 Java 9 和 10 及更高版本(和 8),使用反射来避免引发此错误

    protected static JavaFileManager getJavaFileManager(ProcessingEnvironment env) {
        JavaFileManager fm = null;

        try {
            /*
             * Context context = ((JavacProcessingEnvironment) env).getContext();
             */
            Method getContext = env.getClass().getMethod("getContext");
            Object context = getContext.invoke(env);
            /*
             * fm = context.get(JavaFileManager.class);
             */
            Method get = context.getClass().getMethod("get", Class.class);

            fm = (JavaFileManager) get.invoke(context, JavaFileManager.class);
        } catch (Exception exception) {
        }

        return fm;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM