【问题标题】:class.getResource() is null though it is in classpathclass.getResource() 为 null,尽管它在类路径中
【发布时间】:2014-03-01 22:12:28
【问题描述】:

我有一个包含项目主类的 jar。这取决于驻留在lib 目录中的其他几个jar。一类这样的依赖 jar 加载资源"/Data/foo/bar/file.txt"。但是将此文件作为资源加载会导致 null。

目录结构如下:

./main.jar
./lib/lib1.jar
./lib/lib2.jar
./lib/lib3.jar
./lib/runtimedata/Data/foo/bar/file.txt

这是 main.jar 的 manifest.mf 的类路径:

lib/lib1.jar lib/lib2.jar lib/lib3.jar lib/runtimedata

我通过

启动应用程序
java -jar main.jar

lib2.jar 包含一个尝试加载文件的类

ThatClass.class.getResource("/Data/foo/bar/file.txt");

但这恰好是空的。为什么? lib/runtimedata 在类路径中。 我什至尝试将Data 目录放入lib/lib/runtimedata,以防路径相对于包含加载类的jar 文件。但这无济于事。

我在这里做错了什么?

编辑

使用

运行应用程序
java -cp main.jar:lib/*.jar:lib/runtimedata my.package.Main

工作正常。

编辑 2

我无法更改执行资源加载的库。我只使用那个库。我唯一可以改变的是 main.jar 类路径和命令行。

【问题讨论】:

  • 我总是使用X.class.getClassLoader().getResource("file.txt")。也许这有帮助。试试ThatClass.class.getClassLoader().getResource("/Data/foo/bar/file.txt");
  • @marioosh 不,它没有。我很抱歉。但我无法更改使用的库。我必须按原样使用它们。我只能设置类路径和应用程序的启动方式。

标签: java jar null resources classpath


【解决方案1】:

当您以“/”开头的路径时,它被认为是绝对的。试试ThatClass.class.getResource("/runtime/Data/foo/bar/file.txt");

否则,如果无法更改代码,请将文件放在 /Data/foo/bar/file.txt

【讨论】:

  • 我不这么认为。以"/" 开头的路径是绝对路径。那是正确的。但它应该是绝对的类路径。对文件系统来说不是绝对的。由于我已将 "lib/runtimedata" 添加到类路径中,因此这应该提供正确的根目录。例如,我没有将"/""." 放到类路径中。因此,将 Data 目录放入文件系统的根目录或 main.jar 的目录应该没有帮助。
【解决方案2】:

在开发环境中,有时会在构建过程中未处理资源时发生这种情况。使用 Gradle 并构建你的主 JAR 或主测试 JAR 将取决于你的库中的 compileJava 任务,但不会触发它们的资源被处理。您可以通过查看构建目录来查看是否发生了这种情况,以查看您的库的资源是否已被复制。如果它们没有被复制,资源加载器将不会在运行时找到它们。

如果这是问题所在,完整的构建将解决该问题,并且已发布的 JAR 应该始终拥有其资源。但是,很高兴能够触发例如单个模块的测试任务,并且知道它总是会拉入它需要的一切。如果您有一个包含必须始终存在的基本资源的库,您可以通过将其添加到库的 build.gradle 来强制它们在部分构建中进行处理:

    compileJava.dependsOn(processResources)

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 2013-10-06
    • 2011-11-27
    • 1970-01-01
    • 2016-12-02
    • 2012-07-03
    • 2019-11-06
    • 2011-09-04
    相关资源
    最近更新 更多