Generated .jar is unable to load some media files - java

I built a java program using IntelliJ. This program loads media files like an image (.jpg) and audio (.wav).
When i run my project inside of the IDE, it works fine.
But when i generate a .jar file of my project, the image and audio files will not load.
When i try to load the .wav audio file, i get a FileNotFoundException
When i try to load the .jpg file, i get an IIOException: Can't read the input file!
I'm loading the image like this:
image = ImageIO.read(ImageScreen.class.getResourceAsStream("/quiz/resources/images/image_1.jpg"));`
When i inspect the top of the stack trace in the debugger, i can see: javax.imageio.ImageIO.read(Unkown Source).
In other parts of my application, i'm able to load text files from a similar directory like this and it works in the .jar file too:
reader = new BufferedReader(
new InputStreamReader(
WordScreen.class.getResourceAsStream(
"/quiz/resources/words/wordlist.txt")));`
I only have one package called quiz in my project and i don't understand why this isn't working, as i am specifying an absolute path.
I've looked at other questions such as this one, but in my opinion, i'm doing what is being suggested.

Thank you everyone for your help. I have managed to find a fix for my problem.
I have changed this:
image = ImageIO.read(ImageScreen.class.getResourceAsStream("/quiz/resources/images/image_1.jpg"));
To this:
image = ImageIO.read(this.getClass().getResourceAsStream("/quiz/resources/images/image_1.jpg"));
I am now retrieving the .wav in the same way and it is working:
this.getClass().getResourceAsStream("/quiz/resources/audio/audio1.wav");

try with getClassLoader()
this.getClass().getClassLoader().getResourceAsStream...

Related

(Java) Trouble going between URLs and files with a .jar file

I'm making a rather big program in java. It has lots of files, including images, audio, and text files. When I'm running from Eclipse, the code I use works fine. However, I always have trouble gaining access to them from a .jar file that's on its own.
I'll give you an example of how I'm coding this.
For the BufferedImage, I have it this way:
File bgImgFile = new File("images/nature.jpg");
BufferedImage bgImg = ImageIO.read(bgImgFile);
For the AudioInputStream, I have:
File soundFile = new File("audio/two.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
And for the text file, I have:
FileReader reader = new FileReader("scripts/0.txt");
This all works fine for when I'm in Eclipse. However, I'm thinking about what I'll want to do for distribution. I want to have a .jar file that can run anywhere, and doesn't need to be in the same directory as those folders containing the files. I've done this before and it's worked fine.
This is what I tried to do for the image:
URL bgFileUrl = MainClass.class.getClassLoader().getResource("images/nature.jpg");
File bgImgFile = new File(bgFileUrl.getFile());
BufferedImage bgImg = ImageIO.read(bgImgFile);
I did similar things for the audio and text file. However, even when I tried in different combinations of having the files themselves in the same directory, having a slash in front of the plain file name, etc., nothing worked. I want to be able to include these files in the .jar file so I don't have to run the .jar from that specific folder.
One thing I don't understand is that, when I opened up the .jar file made using my original code, the images, audio, and scripts folders were in there and they had my files. They were there. However, when I tried to run it, I got an IIOException ("Can't read input file!") and a NullPointerException, even though I was using the same code as before.
How do I make it so the files are included in the .jar file so it can run on its own?
Thanks for the help!
Can you try below code
URL audioFileUrl = MainClass.class.getClassLoader().getResource("audio/two.wav"");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(audioFileUrl);

Java: Reading in an image from same folder as java files

I have code that reads in an image file from the same directory as the java files, but currently I can only get it to work if the entier path is given.
picture = new JLabel(new ImageIcon(ImageIO.read(new File("C:\\Users\\...\\ogre.png"))));
The image is in the same folder as the java files. But when I try just "ogre.png" or ".\\ogre.png" or similar it does not work.
My question is this:
I will be exporting to a JAR eventually, will this affect that once the jar is created? (I'm assuming yes, since creating a jar doesnt change the source code).
How can I read the file from the same folder instead of the exact file path, In a situation where the containing folder were to be moved for example.
This is the standard way... (and it will work when everything is in the jar)
URL url = OneOfYourClass.class.getResource("package/pathTo/image/ogre.png");
ImageIcon image = new ImageIcon(url);
OneOfYourClass is a class that you have (maybe the main class)
package/pathTo/image/ is the path from this class to find your image

Playing an MP3 in a jar with mp3spi

I'm working on a Java project in Eclipse IDE. I want to deploy the project into a jar-file. Getting the audio to run is the part I have diffictuly with. I'm using the mp3spi library by javazoom for playing mp3 files. ( http://www.javazoom.net/mp3spi/sources.html )
I implemented my AudioPlayer almost like the sample on the javazoom website. ( http://www.javazoom.net/mp3spi/documents.html )
I could post the lengthy code here again, but it's almost the same with the difference that my AudioPlayer extends Thread so it can play independently. (and it works just fine in the development environment)
The problem I have is that I just can't get it to run when I export the project into a jar. I found already many questions and suggestions to this topic and I tried most of it. Sadly I still don't have a working solution. I'm sure it's out there but at this point I might miss the forest for the trees.
All the required libraries (jl1.0.1.jar, tritonus_share.jar and mp3spi1.9.5.jar) are in my jar and added to the classpath.
The curcial point of the code seems to be AudioInputStream (at line 10 in the sample) which takes a File to be created.
1st attempt - the code like suggested on javazoom.net:
File file = new File("src/resources/audio/test.mp3");
AudioInputStream ain = AudioSystem.getAudioInputStream(file);
What happens is:
Eclipse IDE:
Works fine, the mp3 plays.
Exported jar-File:
Jar works but mp3 does not play.
Exported jar-File opend with windows console:
Jar works but mp3 does not play.
Error messages: at audio.AudioPlayer.run(AudioPlayer.java:40)
java.io.FileNotFoundException: src\resources\audio\test.mp3
So I can't use „File“ in a jar because I'm not dealing with a file in the file system but a file inside my jar.
2nd attempt
URL url = ClassLoader.getSystemResource("resources/audio/test.mp3");
AudioInputStream ain = AudioSystem.getAudioInputStream(url);
What happens is:
Eclipse IDE:
Works fine, the mp3 plays.
Exported jar-File:
Jar works but mp3 does not play.
Exported jar-File opend with windows console:
Jar works but mp3 does not play.
Error messages: javax.sound.sampled.UnsupportedAudioFileException:
could not get audio input stream from input URL
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at audio.AudioPlayer.run(AudioPlayer.java:40)
I can't get an AudioInputStream from a URL? I don't know. So let's get to ...
3rd and 4th attempt
Attempt 3:
BufferedInputStream myStream = new BufferedInputStream(getClass().getResourceAsStream("/resources/audio/test.mp3"));
AudioInputStream ain = AudioSystem.getAudioInputStream(myStream);
Attempt 4:
BufferedInputStream myStream = new BufferedInputStream(ClassLoader.getSystemResourceAsStream("resources/audio/test.mp3"));
AudioInputStream ain = AudioSystem.getAudioInputStream(myStream);
Again both with the result playing in Eclipse IDE but not in the jar.
Exported jar-File opend with windows console:
Jar works but mp3 does not play.
Error messages: javax.sound.sampled.UnsupportedAudioFileException:
could not get audio input stream from input stream
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at audio.AudioPlayer.run(AudioPlayer.java:40)
I am really lost here. Any help would be much appreciated.
Related topics:
File path or file location for Java - new file()
Reading File In JAR using Relative Path
Java Audio Stream (mp3spi lib), UnsupportedAudioFileException
Jar with compressed music with java?
I used to export my project always as a jar and all images that I loaded in a similar manner would load properly while the audio file would not.
Now, that I tried to export my project as a runnable jar, it works just fine (attempt 4, maybe other attempts as well). The following question and answer explains the difference between jar and runnable jar.
Java Eclipse: Difference between exporting as a JAR and exporting as a Runnable JAR
How that manifest file impacts the proper loading of resources with
ClassLoader.getSystemResourceAsStream
is beyond me, but apparently it does.
Somebody might want to elaborate on those maifest files because I really can't. Or perhaps there are other differences between the export of a jar and a runnable jar.
Since I have a working solution I am done for now with this subject.

Java - Audio URL

I have a audio file stored in a folder within the project and I'm trying to call the sound file within the folder.
I am able to call the file using the full URL
new java.net.URL("file:C:\NetBeansProjects\Puzzle\audio\applause2.wav"));
But is there a way to shorten it so that if I move the project I don't require changing the code?
Thanks
File file = new File("audio\applause2.wav");
Assuming you keep the audio folder at the same level relative to the jar

Images are not displaying in jar but displaying in compiler?

I know, I know, this has been asked before. But every resource I've looked at uses IconImages while I just have plain Images.
Is there a different solution? Please help as I've been stuck researching and trying to figure this out for days now with no progress.
Image Floor = Toolkit.getDefaultToolkit().getImage("Floor.PNG");
EDIT: If I was to make sure the jar wouldn't compress and I created a seperate directory in the jar for images and put the correct file path, would this code work?
Toolkit#getImage(String s) looks for a file and likely your image is in the Jar and is now a resource not a file. Look to using resources for this.
Note that ImageIO.read(...) can accept an InputStream parameter the Class class has a method, getResourceAsStream(...) which can put the resource into a Stream that ImageIO can read. Give that a try.
Also, are you getting any error messages when you try what you're doing?
Make sure you know what your current directory is, and how it relates to the position of the files in your jar.
Here's how I would handle it.
1) Require there to be a file called "images.txt" in the directory with your jar (or bundle it into the jar.)
2) Make a file called "images.txt" with a format like `FLOOR:C:\\images\\floor.png`
3) Load this file into memory on load.
4) Load your images based on the entries in the file
This will give you the advantage of changing your images without changing your code if it's defined outside the jar :)
It's not loading because you're not putting the path to the images in the declaration. It expects the images to be wherever the jar is (notice there's no directories there)
You need to offload the definition of the file names to a file, or at the very least guarantee the relative position of the files.
Another good option is to put the images in the jar itself, say in an img directory, and reference them there. But then changes to the images require a new jar, which may not be desired for development purposes.
The getImage call is looking in the file system working directory, not inside the Jar file. This is why the jar file loads the images successfully when they are placed in the same directory outside the jar file. If the images are bundled in the jar file, they are no longer file system files to be accessed, but rather Jar file resources. There is a different way to load these, but sorry, I don't know it off the top of my head.
Check the extension of files. I had this problem because the extension was "PNG", when I changed it to "png", everything was ok.
You can't expect a JAR file to magically know where your images are. If you put a JAR file alone on the desktop, it's going to look for the files on the desktop! The code
getImage("Floor.png")
searches the current directory of the JAR (or source project) by default and you'd expect that if the JAR was in the same directory, it would work. If the JAR is on the desktop how does it know where Floor.png is? Of course, you can specify a hard-coded path
getImage("C:\Some Folder Path\Floor.png")
but then Floor.png has to be in C:\Some Folder Path\ for the JAR to work properly.
It sounds like what you really want to do is keep the images in the JAR file (which acts like a ZIP file). The tutorial on doing that is here:
http://download.oracle.com/javase/tutorial/uiswing/components/icon.html#getresource
And I know for ImageIcon you use: new javax.swing.ImageIcon(getClass().getResource("myimage.jpeg") but I have not found anything similar for plain Image.
<head-desk /> You should really get into reading the JavaDocs. Otherwise you are 'coding by magic'. Which generally won't work.
URL urlToImage = getClass().getResource("myimage.jpeg");
// If you need to support Java 1.3
Image image = Toolkit.getDefaultToolKit().getImage(urlToImage);
// If your users have dragged their JRE into this millennium
BufferedImage bufferedImage = ImageIO.read(urlToImage);

Categories

Resources