1

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.

enter image description here

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.

craftdeer
  • 985
  • 5
  • 20
  • 36
  • You are using FXML, so I suggest you use its internationalization capabilities rather than manually setting values. See for example: [the eden coding guide sections on interationalization](https://edencoding.com/dependency-injection/), [JavaFX and internationalization](https://stackoverflow.com/questions/10143392/javafx-2-and-internationalization) and [SceneBuilder: Internationalizing Your FXML Layout](https://docs.oracle.com/javafx/scenebuilder/1/user_guide/i18n-support.htm). – jewelsea Nov 09 '21 at 21:46
  • 1
    @jewelsea I have edit my question to show how how I created the jar file. – craftdeer Nov 09 '21 at 22:14
  • 1
    @jewelsea You are right. Changing the case to lower fixed it. – craftdeer Nov 10 '21 at 05:22
  • Replaced comments with an answer. – jewelsea Nov 10 '21 at 06:28

1 Answers1

1

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.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • 1
    It is even worse. On Macs this can be configured by the user: https://discussions.apple.com/thread/251191099 so it may work on one Mac and fail on another. – mipa Nov 10 '21 at 09:15