如何在Java批注处理器中获取正确的JavaFileManager? [英] How to obtain the right JavaFileManager in a Java annotation processor?

查看:106
本文介绍了如何在Java批注处理器中获取正确的JavaFileManager?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经通过扩展 javax.annotation.processing.AbstractProcessor 编写了Java注释处理器,在Eclipse上下文中调用了它,并且工作正常,只是我需要有关源路径和路径的更多信息.我的处理器可以工作的类路径:

I've written an Java annotation processor by extending javax.annotation.processing.AbstractProcessor which is called in the Eclipse context and it works fine, except that I need more information about the source path and class path for my processor to work:

@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特定接口的解决方案.

The question is how to retrieve in the annotation processing context (the implementation of process) a valid JavaFileManager which can give me the source path and the classpath of the compiler which is currently executing the annotation processor. Preferably, I would find out about a solution which does not involve a dependency on Eclipse/JDT specific interfaces.

我尝试了以下无效有效的方法:

I've tried the following which does not work:

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和更低版本:

For Java 8 and before:

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),请使用反射来避免对此打勾错误:

For Java 9 and 10 and later (and 8), use reflection to avoid tickling this 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;
    }

这篇关于如何在Java批注处理器中获取正确的JavaFileManager?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆