Reputation: 494
I have a problem with opening .jar file built by IntelliJ.
It throws an exception:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at application.MainApp.initRootLayout(MainApp.java:51)
at application.MainApp.start(MainApp.java:42)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more
Exception running application application.MainApp
but, when I try to run my program with IntelliJ (Run -> Run "MainApp") it runs without any problem. Could you help me ?
MainApp.java
package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import model.Person;
import view.PersonEditDialogController;
import view.PersonOverviewController;
import java.io.IOException;
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Person> personData = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
public MainApp() throws IOException {
personData.add(new Person("Name Surname"));
personData.add(new Person("Name Surname"));
personData.add(new Person("Name Surname"));
}
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("My Application Title");
initRootLayout();
showPersonOverview();
}
public void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("../view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
public void showPersonOverview() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("../view/PersonOverview.fxml"));
AnchorPane personOverview = (AnchorPane) loader.load();
rootLayout.setCenter(personOverview);
PersonOverviewController controller = loader.getController();
controller.setMainApp(this);
}
catch (IOException ex) {
ex.printStackTrace();
}
}
public boolean showPersonEditDialog(Person person) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("../view/PersonEditDialog.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Edit Person");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
PersonEditDialogController controller = loader.getController();
controller.setDialogStage(dialogStage);
controller.setPerson(person);
dialogStage.showAndWait();
return controller.isOkClicked();
}
catch (IOException ex) {
ex.printStackTrace();
return false;
}
}
public Stage getPrimaryStage() {
return primaryStage;
}
public ObservableList<Person> getPersonData() {
return personData;
}
}
Upvotes: 1
Views: 275
Reputation: 25573
My guess would be that MainApp.class.getResource("../view/PersonOverview.fxml")
returns 'null' if it is called in the context of a .jar. This means setLocation(null)
is called which explains why the exception says there is no location.
Resource loading behaves differently depending on the class loader. In IntelliJ (using run) it returns a URI for the file on the hard disk, while it would return a URI to the file within the .jar for the latter case. The thing that is probably breaking it is the relative location of the asset ("..").
Specifing an absolute location given the resource root ("/view/PersonOverview.fxml") will probably fix the problem, although some testing may be required.
Upvotes: 2