Issue
I have a resource bundle with language properties. If the local language is French, it loads french texts or else default English. My program works okay when using Intellij but when I create the jar file and try to run it by doing java -jar myapp.jar
then it crashes and shows error.
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: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:file:/C:/Users/rsoph/OneDrive/Desktop/C195new/out/artifacts/C195_Project_jar/C195_Project.jar!/view/login_welcome_screen.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2595)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
at main.Main.start(Main.java:33)
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.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 com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
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 com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2591)
... 17 more
Caused by: java.util.MissingResourceException: Can't find bundle for base name lng, locale en_US
at java.base/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2055)
at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1689)
at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1593)
at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1556)
at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:932)
at controller.LoginWelcomeScreenController.initialize(LoginWelcomeScreenController.java:61)
... 29 more
This is how I use the resource bundle
ResourceBundle resBundle = ResourceBundle.getBundle("lng", Locale.getDefault());
if (Locale.getDefault().getLanguage().equals("fr")) {
usernameLabel.setText(resBundle.getString("username"));
passwordLabel.setText(resBundle.getString("password"));
loginButton.setText(resBundle.getString("login"));
exitButton.setText(resBundle.getString("exit"));
}
My program structure looks like this.
EDIT: This is how I created the jar executable file.
File -> Project Structure -> Artifacts -> click on the plus sign (+) -> Jar -> From modules with dependencies. Select the main class and OK. Followed by Clicking on the + sign and adding all files from the javafx bin folder to the File ( all the dll files). Go to Build -> Build artifacts -> Build.
Solution
The bundle name you are looking up is "lng", but your the files in your bundle have prefixes of "Lng".
The case of the resource file name and the bundle lookup string should match.
If you are using a Windows system, the lookup on the file name is case-insensitive when using the file protocol to access the unpackaged resources.
But, when packaged in a jar, the lookup of the resources using the jar protocol is case sensitive.
Which explains why you can find the resources when not packaged in a jar, and why the lookup fails after jar packaging.
In addition to the issue with the jar packaging, relying on case insensitive file names also means that the project would fail if used on an OS with a case sensitive file system, like a Mac or Linux system.
Answered By - jewelsea
Answer Checked By - Mary Flores (JavaFixing Volunteer)