2015-05-14 100 views
3

我們正在建設使用ScalaFX申請後讀取XML文件。當我在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) 

罐結構:

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

+0

嗯,這很有趣 - 我用它在Q1提到非常相似的代碼和'getResourceAsStream'行之有效的我(使用'sbt-assembly')。我建議你在沒有JavaFX的情況下設置一個新的空白應用程序,並嘗試加載XML資源。如果它不起作用,你有一個更簡單的問題來處理。如果有效,問題可能是JavaFX。在這種情況下,你更瞭解這個問題。現在我無法幫助你,然後提出進一步的問題分析:) – petrbel

+0

@petrbel,getResourceAsStream也適用於我。但ScalaFX方法需要一個URL,而不是一個流。爲此,我使用了getResource。這是什麼給予​​的問題:( –

+0

我看,我提供了一個更長的解釋作爲答案 - 希望它澄清:) – petrbel

回答

0

真正的問題是相當棘手首先,我們需要認識到,JAR是檔案(例如,類似於ZIP。 )和歸檔文件是常規文件,因此歸檔文件本身位於文件系統的某個位置,因此它可以通過URL訪問。

相反,「子文件」(條目)只是數據塊w在檔案中。操作系統和JVM都不知道這個特定的文件是一個檔案,因此他們認爲它是一個常規文件。

如果您有興趣進行更深入的檔案處理,請嘗試瞭解ZipFile的工作原理。 JAR基本上是ZIP,所以你可以將這個類應用到它。

Java提供Class.getResourceAsStream方法,使程序員可以讀取文件的流。這個解決方案在這個特定的例子中顯然沒有用處,因爲ScalaFX方法預計代替File

所以基本上你有三個選擇

  1. 使用流API,以複製XML到臨時文件,超過此文件傳遞給方法。
  2. 分開部署資源的方式是保留常規文件。
  3. 以接受流重新實現的JavaFX(可能應該無論如何發生)