I'm trying to load a WAV resource file inside my JAR file. It works perfectly when running via the IDE. But when running via java -jar
, it gives me about 75% garbage and 25% of the correct data. I would like to know why. Here are a few methods I tried:
(my preferred method): Read with getResourceAsStream from JAR gives corrupted data that has some parts of the original:
short[] waveform = AudioFileAPI.readWavFile(
Blah.class.getResourceAsStream("/blah.wav"));
read from regular file: OK
waveform = AudioFileAPI.readWavFile(new File("C:\\blah\\blah.wav"));
extract wav from the created JAR and read it as a regular file: OK
waveform = AudioFileAPI.readWavFile(new File("C:\\blah\\fromjar.wav"));
read with getResource and call play() on AppletAudioClip gives 75% corrupted data as above.
Object o = Blah.class.getResource("/blah.wav").getContent();
AppletAudioClip appletAudioClip = (AppletAudioClip) o;
appletAudioClip.play();
read via getResource().openStream(): 75% corrupted data as above.
InputStream is = Blah.class.getResource("/blah.wav").openStream();
waveform = AudioFileAPI.readWavFile(is);
unzip and re-zip JAR and re-run the program doesn't help either.
To recap, all above methods work perfectly when run from the IDE, but the indicated ones fail when loading as a resource. The JAR was packaged by IntelliJ IDEA. I use JDK version 1.8.0_131. AudioFileAPI is my own class.
This was actually due to a bug in the code that was reading the resource's InputStream. In cases where the InputStream's read()
method did not read all bytes in one go for whatever reason, subsequent read()
attempts would incorrectly write into the same buffer always starting at position 0, instead of starting at the position determined by the total number bytes read so far.
So, in the end, the buffer looked like it had fragments of the correct data at the beginning, and garbage at the end.