【问题标题】:Issues with reading xml file after creating jar创建 jar 后读取 xml 文件的问题
【发布时间】:2015-05-15 22:37:35
【问题描述】:

我们正在使用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)

Jar 结构:

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

【问题讨论】:

  • 嗯,这很有趣——我使用了非常相似的代码,而第一季度提到的getResourceAsStream 对我来说效果很好(使用sbt-assembly)。我建议您设置一个没有 JavaFX 的新空白应用程序并尝试加载 XML 资源。如果它不起作用,您需要处理一个更简单的问题。如果它有效,问题可能是 JavaFX。在这种情况下,您对问题的了解更多。现在我不能帮助你更多然后建议进一步的问题分析:)
  • @petrbel,getResourceAsStream 也适用于我。但是 ScalaFX 方法需要一个 URL,而不是流。为此,我使用了 getResource。这就是问题所在:(
  • 我明白了,我提供了一个更长的解释作为答案 - 希望它能澄清它:)

标签: scala jar fxml scalafx onejar


【解决方案1】:

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

相反,“子文件”(条目)只是存档中的数据块。操作系统和 JVM 都不知道这个特定文件是档案,因此它们将其视为常规文件。

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

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

所以基本上你有三个选择

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-27
    • 2013-09-13
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2016-07-20
    相关资源
    最近更新 更多