繁体   English   中英

无法从jar获取资源

[英]Can't get resources from jar

在我的项目中,我需要从资源中的文件夹中获取 json。 为此我实现了这个方法:

protected def getListOfJsonFromResources(path: String): List[String] = {
  val source = Source.fromInputStream(Thread.currentThread().getContextClassLoader.getResourceAsStream(path))
  println(source)
  val list = source.getLines().map{file =>
    Source.fromInputStream(Thread.currentThread().getContextClassLoader.getResourceAsStream(path + file))
      .mkString
  }.toList
  source.close()
  list
}

它在 IDE 中工作正常,但当我运行我的 jar 时没有返回任何内容。我知道问题出在val source中,因为在 jar 中它返回空迭代器。 我已经尝试使用this.getClass().getResourceAsStream()this.getClass().getClassLoader().getResourceAsStream()并将此方法重写为 java 方法。

我在 Idea(Build>Build Artifacts>Build)中生成 JAR。 此文件位于 JAR 内,路径正确。 我使用 Apache Maven 3.6.3 我的 res 文件夹:resources/folder/json/jsonFolder path:folder/json/jsonFolder/

我应该如何更改此方法以从给定文件夹中获取 json 列表?

预先感谢。

正确的用法实际上是MyClass.class.getResourceAsStream 毕竟,如果您的代码被子类化, getClass().getRAS()将会失败。 但是,我认为它不是 - 因此更改将改进此代码的样式并在未来证明它,但它可能不会直接解决问题。

MyClass.class.getRAS所做的是查看MyClass.class文件所在的完全相同的位置。 例如,如果您有一个 jar:

META-INF/MANIFEST.MF
com/foo/app/MyClass.class
app-icon.png
com/foo/app/save.png

然后你运行 MyClass,然后MyClass.class.gRAS("save.png")就会运行。 正如MyClass.class.gRAS("/app-icon.png") - 注意前导斜杠。

因此,如果 gRAS 在这里不适合您,那么结论是您指定了错误的路径,或者您需要包含在应用程序中的文件未包含在您的构建工具中。

您没有显示任何与您的构建脚本相关的内容,因此关于如何解决这个问题没有太多可说的。 但我可以为您提供调试问题所需的工具,这样您就可以使用这个有用的技巧自行修复它:

MyClass.class.getResource("MyClass.class")

适用于任何 class。打印它( System.out.println上面调用中的 URL),您将看到 URL,它准确地告诉您实际使用了 MyClass 的许多变体中的哪一个(通过你的 IDE 的构建保存,由 sbt 的构建工具,在 dist 阶段由 sbt 生成的 jar 文件中,谁知道磁盘上的某个地方还有多少。)。

现在使用标准的计算机工具(Mac:Finder,windows:Explorer,或者只使用命令行)导航到实际位置并检查此资源文件是否存在。 请注意,jar 个文件只是 zip 个文件; unzip -l somejar.jar在这里很有用。

如果您看到该文件,那么,现在您知道该文件相对于MyClass.class的位置,并且现在您知道向gRAS调用提供什么。 请注意..不是一个好主意; 如果它不在与您的 class 相同的目录中并且不在任何子目录中,则使用前导斜杠指向 jar 文件或类路径根目录的“root”之外的 go。

如果您没有看到该文件,那么,现在您知道您的构建已损坏。 搜索 web(或在 SO 上的单独问题中询问)以了解如何解决该问题,现在您无需重复构建和运行整个应用程序即可解决问题; 您可以简单地继续扫描构建工具生成的 jar 文件,直到资源文件出现在正确的位置。

注意:ClassLoader.getSystemCLassLoader.getResource、getThreadContext().getResource、getClass().getResource - 这些都是错误的。 不要那样做。 它也可能会工作,但它的代码更多,并且会在各种情况下中断。 MyClass.class.getResource完全符合您的要求,是惯用的,并且是最短的 forms 之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM