创建 jar 后读取 xml 文件的问题

Issues with reading xml file after creating jar

我们正在使用 ScalaFX 构建应用程序。当我 运行 IntelliJIDEA 中的项目时,一切正常。但是,当我创建 jar 文件并尝试执行它时,我在读取某些 xml 文件时遇到错误。 我尝试了 SO 中发布的各种解决方案,但没有用。

package com.app.adt

import scalafx.application.JFXApp
import scalafx.Includes._
import scalafx.scene.Scene
import scala.reflect.runtime.universe.typeOf
import scalafxml.core.{FXMLView, DependenciesByType}

object App extends JFXApp {

  val root = FXMLView(getClass.getResource("/com/app/adt/Home.fxml"),
    new DependenciesByType(Map(
      typeOf[TestDependency] -> new TestDependency("ADT"))))

  stage = new JFXApp.PrimaryStage() {
    title = "ADT"
    scene = new Scene(root)
  }
}

xml 文件(Home.fxml) 放在com/app/adt 包中。我正在使用 sbt-one-jar 创建 jar 文件。

我试过不同的路径组合,但总是报同样的错误。

错误堆栈:

Caused by: javafx.fxml.LoadException:
file:/adt-app_2.11-1.3-SNAPSHOT-one-jar.jar!/main/adt-app_2.11-1.3-S
NAPSHOT.jar!/com/app/adt/Home.fxml

        at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2611)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2589)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2435)
        at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2403)
        at scalafxml.core.FXMLView$.apply(FXMLView.scala:17)

罐子结构:

adt-app_2.11-1.3-SNAPSHOT-one-jar.jar
   |
   main
       |
       adt-app_2.11-1.3-SNAPSHOT.jar
            |
             com\app\adt
                       |
                       App.scala
                       Home.fxml

此外,我尝试使用 sbt-assembly 而不是 sbt-one-jar。但是,仍然出现相同的错误。 :(

在 SO 中尝试了以下答案:

Q1

Q2

真正的问题比较棘手。首先,需要认识到 JAR 是一个归档文件(例如类似于 ZIP),而归档文件是常规文件。因此存档本身位于文件系统中的某个位置,因此可以通过 URL.

访问

相反,"subfiles"(条目)只是存档中的数据块。操作系统和 JVM 都不知道这个特定文件是一个存档,因此它们将其视为一个普通文件。

如果您对更深入的归档处理感兴趣,请尝试了解 ZipFile 的工作原理。 JAR 基本上是 ZIP,因此您可以将此 class 应用于它。

Java 提供了 Class.getResourceAsStream 方法,使程序员能够将文件作为流读取。此解决方案在此特定示例中显然无用,因为 ScalaFX 方法需要 File 代替。

所以基本上你有三个选择

  1. 使用流 API 将 XML 复制到临时文件中,然后将此文件传递给方法。
  2. 以保留常规文件的方式单独部署您的资源。
  3. 重新实现 JavaFX 以接受流(无论如何这应该会发生)