【问题标题】:How to obtain the right JavaFileManager in a Java annotation processor?如何在 Java 注释处理器中获取正确的 JavaFileManager?
【发布时间】:2015-06-21 21:18:13
【问题描述】:

我通过扩展在 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 eclipse annotation-processing


【解决方案1】:

对于 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),请使用反射来避免对它发痒 bug:

    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;
    }

【讨论】:

    猜你喜欢
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    相关资源
    最近更新 更多