I'm packaging my JavaFX project as installer using JPackageScriptFX, and I've created a folder called "resources" which is present at the basedir of my source package. I've included this folder in my package by passing --app-content resources
flag:
$JAVA_HOME/bin/jpackage \
--type $INSTALLER_TYPE \
--dest target/installer \
--input target/libs \
--app-content resources \
--name "$NAME" \
--vendor "$VENDOR" \
--main-class ${MAIN_CLASS}.AppLauncher \
--main-jar ${MAIN_JAR} \
--java-options -Xmx2048m \
--runtime-image target/java-runtime \
--icon ${ICON} \
--app-version ${APP_VERSION} \
This is my source code folders directory structure:
Project
|
|-resources
| |-icon.png
|
|-src
|
|-pom.xml
.
.
.
After the package is created and installed successfully, the installation directory's structure is:
Project
|
|-bin
| |-project
|
|-lib
| |-app
| | |-project.jar
| | |-project.cfg
| |
| |-resources
| | |-icon.png
| |
| |-runtime
|
|-share
When I'm running the project, I'm getting the FileNotFoundException
on method:
DBIO.loadResource
public class DBIO {
private DBIO(){/*NOTHING*/}
private static InputStream loadResource(String path){
try{
return new FileInputStream("resources/"+path);
}catch(IOException ex){
ex.printStackTrace();
}
return null;
}
public static final Image LOGO = new Image(loadResource("icon.png"));
}
java.io.FileNotFoundException: resources/icon.png (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(Unknown Source)
at java.base/java.io.FileInputStream.<init>(Unknown Source)
at java.base/java.io.FileInputStream.<init>(Unknown Source)
at project.app.DBIO.loadResource(DBIO.java:24)
at project.app.DBIO.<clinit>(DBIO.java:30)
at project.app.EULAController.<clinit>(EULAController.java:29)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unknown Source)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(Unknown Source)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(Unknown Source)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(Unknown Source)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:941)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:983)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:230)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:757)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2853)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2649)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2563)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2531)
at project.app.App.start(App.java:16)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$10(GtkApplication.java:263)
at java.base/java.lang.Thread.run(Unknown Source)
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ExceptionInInitializerError
at project.app.EULAController.<clinit>(EULAController.java:29)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unknown Source)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(Unknown Source)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(Unknown Source)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(Unknown Source)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:941)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:983)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:230)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:757)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2853)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2649)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2563)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2531)
at project.app.App.start(App.java:16)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$10(GtkApplication.java:263)
... 1 more
Caused by: java.lang.NullPointerException: Cannot invoke "java.io.File.toPath()" because "file" is null
at project.app.DBIO.writeToFile(DBIO.java:73)
at project.app.Util.log(Util.java:43)
at project.app.DBIO.loadResource(DBIO.java:26)
at project.app.DBIO.<clinit>(DBIO.java:30)
... 27 more
EDIT:
If I copy the resources folder inside Project/bin
the project starts working. That means the program is looking for resources folder inside bin. How should I point it to look in the correct location (inside /lib
)?
resources
folder can be included into a project through jpackage using
--app-content resources
This folder will be present as Project/lib/resources
in Linux and Project\resources
in Windows.
Access to this folder can be made through:
String resourcesDir = new File(getClass().getProtectionDomain().getCodeSource()
.getLocation().getPath()).getParentFile().getParent()+"/resources/";
Points to notice
Image()
) would require you to prefix file://
or file:\\
.URLDecoder.decode(resourcesDir,"UTF-8")
.