Problem:
- Running JavaFX application jar fails though the main
javafx.application.Application
class runs successfully showing a GUI window.
What I have:
- IntelliJ IDEA Community Edition 2021.2.1
- Liberica Full JDK 11.0.12+7 x86 64 bit for Windows(Already includes JavaFX)
- Windows 10 Home 64bit
Project structure(IDE generated, not modified):
main
├───java
│ │ module-info.java
│ │
│ ├───com
│ │ └───tejasb
│ │ └───test
│ │ HelloApplication.java
│ │ HelloController.java
│ │
│ └───META-INF
│ MANIFEST.MF
│
└───resources
└───com
└───tejasb
└───test
hello-view.fxml
Source code:
- HelloApplication.java
package com.tejasb.test;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
- HelloController.java
package com.tejasb.test;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}
- hello-view.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.tejasb.test.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>
- module-info.java
module com.tejasb.test {
requires javafx.controls;
requires javafx.fxml;
opens com.tejasb.test to javafx.fxml;
exports com.tejasb.test;
}
- MANIFEST.MF
Manifest-Version: 1.0
Main-Class: com.tejasb.test.HelloApplication
Exception stack trace(when application jar is ran):
Exception in Application start method
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 javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
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 java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2459)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at com.tejasb.test.HelloApplication.start(HelloApplication.java:14)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
... 1 more
Exception running application com.tejasb.test.HelloApplication
Content of application jar:
Test.jar
│ module-info.class
│
├───com
│ └───tejasb
│ └───test
│ HelloApplication.class
│ HelloController.class
│
├───META-INF
│ MANIFEST.MF
│
└───resources
└───com
└───tejasb
└───test
hello-view.fxml
Steps to reproduce problem:
- Create project in IntelliJ IDEA with project structure as above
- Create new run configuration as
Application
- Set Name, JDK/JRE, -cp from drop down menu and main class as
com.tejasb.test.HelloApplication
- Set Name, JDK/JRE, -cp from drop down menu and main class as
- Go to Project structure>Project settings>Artifacts
- Click + then JAR>From modules with dependencies...
- Set Main class as
com.tejasb.test.HelloApplication
and select copy to the output directory and link via manifest - Click OK then on the right side
- Right click .jar and select Create directory and set name as
resources
- Then right click created directory and select Add copy of>Directory content and select src>main>resources directory (from project)
- Click OK
- Click Run button(application should run successfully showing a window with a button in it)
- Now, click Build>Build artifacts...>build(this should build na application jar file at your specified location)
- Finally, when this generated jar is ran from console, it doesn't work, throws above exception.
What I have tried:
- Setting this
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
to this
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("/hello-view.fxml"));
this throws the same exception as above even in step 4(Of Steps to reproduce problem) and step 5(Of Steps to reproduce problem) is as it was.
- Also, tried to use
HelloApplication.class.getClassLoader().getResource("hello-view.fxml")
andHelloApplication.class.getClassLoader().getResource("/hello-view.fxml")
and what not.... But, the jar throws the same exception.
Any help on this will be appreciated. Thanks