I got an application which is working with resources (.wav .png- files). I want to include those resources in my .jar, when I build my project.
Running the application from the IDE works well.
As described here, I created the resources-folder
at the same level of my src-folder
My project-structure:
ProjectName --
|
out
|
resources --
| |
| sounds
| |
| images
src --
|
...
As described here, I have marked the folder resources
as Resources root
.
As described here, I created my own artifacts in the Project structure
.
Thats how they look like:
The piece of code, that works with an audio file for example:
new Media(new File("resources/sounds/login_sound.wav").toURI().toString());
When I try to run the jar via terminal, Iam getting the following error:
Caused by: MediaException: MEDIA_UNAVAILABLE : /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav (File or directory not found)
The full stack-trace:
moritz@Momix:~/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar$ java -jar TheFloorIsLavaGUI.jar
Gtk-Message: 12:33:12.649: Failed to load module "canberra-gtk-module"
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$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: MediaException: MEDIA_UNAVAILABLE : /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav (Datei oder Verzeichnis nicht gefunden)
at javafx.scene.media.Media.<init>(Media.java:407)
at managers.SoundManager.playSong(SoundManager.java:71)
at main.TheFloorIsLavaGUI.start(TheFloorIsLavaGUI.java:39)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
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$null$48(GtkApplication.java:139)
... 1 more
Exception running application main.TheFloorIsLavaGUI
Any advices? Thank you
TL;DR:
Load the file from the classpath instead of from the filesystem:
new Media(
Test.class.getResource(
"resources/sounds/login_sound.wav"
).toURI().toString())`
Explanation: there are a couple of things going on here:
/your/home/.../project/out/artifacts/.../resources/...
. By marking resources
as a resource folder, you tell IntelliJ to put all files there in the root of the classpath, as shown in the screenshot.It does not put that file in the file system but includes it in the jar
When running from the IDE, new File("resources/sounds/login_sound.wav").toURI()
evaluates to /home/moritz/IdeaProjects/TheFloorIsLavaGUI/resources/sounds/login_sound.wav
which is the location of the file in your project. When running from the jar, it evaluates to the path in the output folder, /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav
, which is not the location the build puts it to.
Now, the correct way of dealing with this is to load the resources not from the file system but from the classpath. Try running the following from the IDE and from the jar to see the difference
System.out.println(new File("foo.wav").toURI().toString());
System.out.println( Test.class.getResource("foo.wav").toURI().toString());
// From IDE
file:/Users/.../untitled/foo.wav
file:/ Users/.../untitled/out/production/untitled/foo.wav
// From Jar
file:/Users/.../untitled/out/artifacts/foo.wav
jar:file: /Users/.../untitled/out/artifacts/untitled_jar/untitled.jar!/foo.wav
Note that Media
accepts jar URIs: https://docs.oracle.com/javafx/2/api/javafx/scene/media/Media.html#Media%28java.lang.String%29
So what you need to to is actually simple.
Change loading the wav from new Media(new File("resources/sounds/login_sound.wav").toURI().toString());
to new Media(Test.class.getResource("resources/sounds/login_sound.wav").toURI().toString())
Besides that: You might want to look into build tools like gradle or maven and not build from the IDE.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With