簡體   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