Включить исключение бросков FXML из .jar - PullRequest
0 голосов
/ 18 ноября 2018

Я пытаюсь включить файл fxml в другой файл и развернуть мое приложение как исполняемый файл.

Файл верхнего уровня fxml загружается следующим образом:

URL location = Editor.class.getClassLoader().getResource("view/app.fxml");
FXMLLoader fxmlLoader = new FXMLLoader(location);
Parent root = fxmlLoader.load();
appController = fxmlLoader.getController();

app.fxml, который находится в «src / view», содержит следующую строку:

<fx:include fx:id="console" source="console.fxml" />

Запуск этого в eclipse будет работать как положено, но при запуске экспортированного файла .jar будет напечатано:

Exception in Application start method
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:61)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javafx.fxml.LoadException:
view/app.fxml:92

        at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
        at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
        at de.hsa.dice.editor.Editor.start(Editor.java:49)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
        ... 1 more
Caused by: java.net.MalformedURLException: Could not open InputStream for URL 'rsrc:console.fxml'
        at org.eclipse.jdt.internal.jarinjarloader.RsrcURLConnection.getInputStream(RsrcURLConnection.java:49)
        at java.base/java.net.URL.openStream(URL.java:1117)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2465)
        at javafx.fxml.FXMLLoader.access$2700(FXMLLoader.java:105)
        at javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1154)
        at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
        at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
        ... 12 more

Обратите внимание, что файл console.fxml находится в том же пакете, что и app.fxml (как в среде IDE, так и в файле .jar).Вот почему я также попробовал source = "./ console.fxml", но ничего не изменилось.

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Чтобы успешно запустить приложение JavaFX как из Eclipse, так и в качестве исполняемого файла JAR, вы можете попробовать использовать абсолютные URL-адреса в app.fxml:

<fx:include fx:id="console" source="/view/console.fxml" />

Таким образом, файлы FXML могут быть загружены также изrunnable jar, который был экспортирован Eclipse.

Существует больше способов упаковать приложение JavaFX отдельно от инструмента экспорта Eclipse, хотя я не проверял, как они ведут себя, когда файлы fxml содержат включениядругие fxml файлы.

0 голосов
/ 25 ноября 2018

Я нашел причину и обходной путь для этой проблемы.

Класс javafx.fxml.FXMLLoader использует этот конструктор URL при создании FXMLLoader для включаемых файлов fxml:

public URL(URL context, String spec)

используя местоположение из конструктора FXMLLoader (location) в качестве контекста и используя «источник» из include-элемента в качестве спецификации.

Так что при загрузке моего корневого fxml-файла с путем «view / app.fxml»,контекст будет пакетом «view» в моей IDE, а корень classpath - в экспортированном .jar.

Я попытался создать URL-адрес приложения с помощью

URL classpath = getClass().getProtectionDomain().getCodeSource().getLocation();
URL location = new URL(classpath, "view/app.fxml");

но мой контекст не будет использоваться снова, когда он снова будет подключен к тому же конструктору позже FXMLLoader.

Так что единственный обходной путь, о котором я могу подумать, - это просто поместить все fxml-файлы (по крайней мере, те, которые стег включения) в корень исходной папки.Таким образом, он будет расположен непосредственно на пути к классам в любой среде.

...