【问题标题】:Cannot load resources in Annotation Processor (Not on classpath)无法在注释处理器中加载资源(不在类路径上)
【发布时间】:2013-08-08 18:34:32
【问题描述】:

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

接口驻留在

MyProject/src/main/java/my.package.MyInterfaces.java.

我想验证驻留在MyProject/src/main/resources/META-INF/resource-bundle/ 中的属性文件是否包含在生成的枚举中定义的键。

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

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

  • 现在我只有处理器所在的 jar 中的资源可用。 我确实尝试通过 eclipse Project/Properties/Java compiler/Annotation processing/Processor options 定义 -classpath 和/或 -sourcepath 但没有成功。

有没有人遇到过这样的问题,谁能告诉我如何让处理器可以使用这些资源?

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

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

谢谢。

【问题讨论】:

  • 是的,好像没有实现。任何人都有解决方法?
  • 这道题大家都解决了吗?我也有类似的问题:stackoverflow.com/questions/29658252/…
  • 比源位置更重要的是输出文件夹中的位置。您是否检查过该文件是否也在输出/META-INF/resource-bundle 中?你如何建造?你的输出文件夹是什么,你在加载包时指定了哪个路径?
  • 为什么不MyProject/src/main/java/my/package/MyInterfaces.java.

标签: java eclipse annotation-processing


【解决方案1】:

问题是绑定到当前线程 (Thread.currentThread().getContextClassLoader()) 的 ClassLoader 在调用 Processor#process 时不是 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());
    //...
}

【讨论】:

  • 我现在正面临着这个问题,处理器就在 Eclipse 中。我尝试了您的解决方法,但仍然找不到资源。你有其他选择吗?
【解决方案2】:

作为一种解决方法,您可以尝试通过命令行参数 -Xboothclasspath/a:path 添加需要使用的类路径,/a 会将路径中的值附加到引导类路径。您需要将此作为命令行选项添加到实际的注释处理运行中,因此在 Eclipse 中将是: 右键project,选择properties,Java Compiler,Annotation Processing,在表中点击New,添加key -Xbootclasspath/a 和要添加的路径作为值。恐怕我还没有尝试过这个进行注释处理,但值得一试!

【讨论】:

    【解决方案3】:

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

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

    如何使该项目的源代码或类路径可供处理器使用,以便加载属性文件?

    您需要将src/main/resources 添加为Eclipse 中的“源文件夹”。首先在 Java 项目的 Eclipse 中选择 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
    

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

    InputStream stream =
        getClass().getClassLoader().getResourceAsStream("x/y/z/jgroups_udp.xml");
    

    顺便说一句,如果你 使用 maven,你会向你添加类似下面的东西 pom.xml:

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多