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

时间:2015-05-14 12:30:31

标签: scala jar fxml scalafx onejar

我们正在使用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文件。

我尝试过不同的路径组合,但是alwasys给出了同样的错误。

错误堆栈:

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

所以基本上你有三个选择

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