-2

This is not a duplicate, because Media objects cannot be initialized with getResourceAsStream(). From the docs: "only HTTP, FILE, and JAR URIs are supported."

My JavaFX project works perfectly when I run it from Eclipse, but breaks when I run the executable JAR that I export. I have tried each type of library handling, but none of it works. I'm using JavaFX 2.2 and Eclipse Oxygen March 2018.

public static Media gameMusic;
public static MediaPlayer gameMusicPlayer;
public static MediaView gameMusicMediaView;

// adds music, once for each audio file to be played
gameMusic = new Media(new File("resources/data/music/Kevin_MacLeod_-_Ouroboros_-_Full_Mix.wav").toURI().toString());
bulletSound = new AudioClip(new File("resources/data/music/Photon gun shot.wav").toURI().toString());
explosionSound = new AudioClip(new File("resources/data/music/Explosion+3.wav").toURI().toString());

The directory structure:

+src
  -source files
+resources
  +data
    +music
      -music files
    +fxml
      -fxml files
    +other folders

The error output:

MediaException: MEDIA_UNAVAILABLE : /Users/username/Desktop/resources/data/music/Kevin_MacLeod_-_Ouroboros_-_Full_Mix.wav (No such file or directory)
at javafx.scene.media.Media.<init>(Media.java:407)
at application.Main.start(Main.java:77)
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)

Note: when I fixed the code for the filepaths to include the executable's name, it breaks in both Eclipse and the executable

wolfy
  • 113
  • 1
  • 7
  • 1
    You need to know the absolute root of the folder where resources are stored, otherwise you cannot find them. Gradle offers a `application` plugin which will create a Windows, Linux and Mac script that will pass the current directory as its first argument. You might also check https://stackoverflow.com/questions/4871051/getting-the-current-working-directory-in-java – M. le Rutte May 20 '18 at 22:14
  • There is no other folder. All of this is getting exported into a single jar file – wolfy May 20 '18 at 22:23
  • @AndrewS just saw your note, Did you try `refer` method? And are your resources placed in same package directory? – UsamaAmjad May 20 '18 at 22:30
  • When you deploy the JAR file, how do you deploy the WAV files? Are they packaged inside the JAR file? Or are they copied along with the JAR file? – Code-Apprentice May 20 '18 at 22:40
  • If you are packaging the WAV files inside the JAR file, then you need to do something like this: https://stackoverflow.com/questions/20389255/reading-a-resource-file-from-within-jar – Code-Apprentice May 20 '18 at 22:41
  • @UsamaAmjad I am not familiar with the `refer` method. – wolfy May 20 '18 at 22:57
  • @Code-Apprentice The exported executable jar has two source folders: `src` & `resources`. The WAVs are stored in `resources`. When I export, I've been telling it to extract the required libraries into the JAR – wolfy May 20 '18 at 23:00
  • If your resources are packaged into the jar you should call `getResource("foo.wav").toString()` on the `class` to get the resource URL. – M. le Rutte May 20 '18 at 23:02
  • Check the links at the top of this page for suggestions about how to read files inside a JAR file. – Code-Apprentice May 20 '18 at 23:55
  • @Code-Apprentice I edited to explain why this is not a duplicate – wolfy May 24 '18 at 23:14
  • @AndrewS read the first link again. It shows how to obtain a jar uri. – Code-Apprentice May 24 '18 at 23:25
  • @Code-Apprentice I must be blind because I only see an example of how to get a file as an InputStream, with no explanation of how to get a URI from said InputStream – wolfy May 24 '18 at 23:43
  • @AndrewS you get a uri for a file inside a jar. No input stream needed: https://stackoverflow.com/a/16240426/1440565 – Code-Apprentice May 25 '18 at 06:12

1 Answers1

-1

The error is pretty simple that it says MEDIA_UNAVAILABLE means that your project is unable to find the resources from the given path. It is probably due to the relative path, you need to provide an Absolute path to find resources from the system.

You could try something like this

Media media = new Media(getHostServices().getDocumentBase() + "/com/projectName/resources/hello.mp3");
MediaPlayer player = new MediaPlayer(media);

EDIT

From the hostServices.getCodeBase() javadoc:

If the application is not packaged in a jar file, this method returns the empty string.

And make sure you have proper imports and extended your app with Application class

import javafx.application.Application;
import javafx.application.HostServices;

public class App extends Application {

}
UsamaAmjad
  • 4,175
  • 3
  • 28
  • 35
  • I did as you suggested, but it threw another error: – wolfy May 20 '18 at 22:54
  • `MediaException: MEDIA_UNAVAILABLE : /Users/andrewsneed/Desktop/com/Escape!/resources/data/music/Kevin_MacLeod_-_Ouroboros_-_Full_Mix.wav (No such file or directory) at javafx.scene.media.Media.(Media.java:407) at application.Main.start(Main.java:77) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)` – wolfy May 20 '18 at 22:56
  • @AndrewS check the updated answer. – UsamaAmjad May 20 '18 at 23:04
  • the updated answer did not help, and the imported libraries were never used. Any other ideas? – wolfy May 24 '18 at 23:27