无法在注释处理器中加载资源(不在类路径上)

时间:2013-08-07 11:39:48

标签: java eclipse annotation-processing

我有一个注释处理器,它将使用接口的getter方法定义的键生成枚举。

界面位于

  

MyProject的/ SRC /主/爪哇/ my.package.MyInterfaces.java。

如果属性文件包含生成的枚举中定义的键,我想验证属于MyProject/src/main/resources/META-INF/resource-bundle/的属性文件。

我的问题是属性文件不能通过处理器的类加载器或Filer.getResource(...)获得。

  • 如何让处理器可以使用此项目的源或类路径,以便我可以加载属性文件?

  • 现在我只有处理器所在的jar中的资源可用。 我尝试通过eclipse项目/属性/ Java编译器/注释处理/处理器选项来定义-classpath和/或-sourcepath,但它没有用完。

有没有人遇到过这样的问题,有谁可以告诉我如何为处理器提供资源?

我确实有maven结构但不使用maven,因为应用程序中的旧依赖项。所以maven现在不适合我。

  

Eclipse 3.6 Helios   似乎StandardLocation.SOURCE_PATHStandardLocation.CLASS_PATH未在Filer#getResource()中实现,因此将生成的源文件或类文件写入SOURCE_PATHCLASS_PATH似乎是不可能的,也可以访问任何文件SOURCE_PATHCLASS_PATH *

上的文件

感谢。

3 个答案:

答案 0 :(得分:1)

问题是,调用Thread.currentThread().getContextClassLoader()时,绑定到当前线程(Processor#process)的ClassLoader不是URLClassLoader。它似乎是一个受限制的类加载器,不允许加载资源。 Javac,eclipse编译器,maven编译器等都会发生这种情况。

幸运的是,您的处理器类将绑定有一个适当的ClassLoader(即getClass().getClassLoader())。

问题是大多数实用程序期望将正确的ClassLoader绑定到线程(最著名的是ServiceLoader和ResourceBundles)。

因此需要解决。当处理器执行时,您可以将ClassLoader重新绑定到当前线程:

@Override
public boolean process(
        Set<? extends TypeElement> annotations,
        RoundEnvironment roundEnv) {

    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    //...
}

答案 1 :(得分:0)

  

我的问题是,属性文件无法通过处理器的类加载器或indexOf()获得。

我不确定我是否理解你的问题。但也许这里的东西会有所帮助。

  

如何让处理器可以使用此项目的源或类路径,以便我可以加载属性文件?

您需要将Filer.getResource(...)添加为&#34;源文件夹&#34;在Eclipse中。首先在Java项目中选择Eclipse中的src/main/resources。然后选择Configure Build Path标签,然后点击Source。您应该可以选择Add Folder文件夹,然后点击src/main/resources。您现在应该在源文件夹列表中看到Ok

如果你查看你的src/main/resources目录,你应该看到那里资源目录中的所有文件,它们会让你知道它们被正确地复制到了类路径中。

target/classes

然后在您的代码中,您可以通过执行以下操作来引用该文件。这将从类路径的顶部加载文件。如果它在一个子目录中,那么你带领:

# files in the src main resources
> ls src/main/resources/x/y/z
jgroups_udp.xml
# should compile into target/classes
> ls target/classes/x/y/z
jgroups_udp.xml org
# and should show up in the jar
> -tvf target/project.jar 
   0 Thu Nov 03 18:50:00 EDT 2016 META-INF/
 135 Thu Nov 03 18:49:58 EDT 2016 META-INF/MANIFEST.MF
 ...
3036 Thu Nov 03 18:49:36 EDT 2016 x/y/z/jgroups_udp.xml

顺便说一下,如果你 使用maven,你会向你添加以下内容InputStream stream = getClass().getClassLoader().getResourceAsStream("x/y/z/jgroups_udp.xml");

pom.xml

答案 2 :(得分:0)

作为一种解决方法,您可以尝试通过命令行参数-Xboothclasspath / a:path添加需要使用的类路径,/ a会将路径中的值附加到引导类路径。您需要将此作为命令行选项添加到实际注释处理运行中,因此在Eclipse中将: 右键单击项目,选择属性,Java编译器,注释处理,单击表中的新建,然后添加键-Xbootclasspath / a和要添加为值的路径。我担心我没有尝试过这种注释处理,但值得一试!