1

I am a beginner, so I'm sorry if the question is too basic.

I've just built a little GUI based program that repeats a certain sound (a short alarm sound right now) continuously after a given amount of seconds, resulting in a sound cycle.

The issue is that when I run the program inside the IDE, it runs perfectly. But, when I build it, the built artifact (the *.jar file) does not work well. I mean, everything works well, but it plays no sound.

I've been searching for answers in the community and I've found some instructions about how to build the artifact properly. At the moment, they were based on a Maven setup most of the times. Either way, I used those answers, but the *.jar file I'm getting has NO resources inside. So, neither the required sound file. I've tried to put the *.wav file manually, using the project artifact options, but this didn't work either, even if I am positively getting the sound file in the built *.jar file artifact.

I've also tried to convert the program to a console one (non GUI) to see any possible exceptions, but then my program didn't play any sound at all. Not even running it from the IDE. So, it's got even worse, and this is, in fact, a different issue that I don't want to mix in here, and I hope I am not wrong on that point.

In most of the answers I've found, they were giving a lot of importance on how the resource was "fetched" inside the code. In fact, it has taught me a better way to do so. I was using quite a weird way to get the absolute path of the file... But then I used:

MyClass.class.getResource("sound.wav");

And now I'm using (with the same result):

ClassLoader.getSystemResource("sound.wav");

Both "resource getting" options had also been tried with a slash bar before the file name ("/sound.wav"), with, again, the same unproductive result as I've already exposed.

Just to make it totally clear, as I mentioned in the question title, I am working with a Gradle project in the IntelliJ IDE.

Thank you in advance for your help.

Ricard Barnes
  • 27
  • 1
  • 9
  • Please zip and share a small sample project ([Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve)). It should work out of the box if you place the wav and other resource files in `src/main/resources` directory. – CrazyCoder May 14 '20 at 20:24
  • Since it is a very small project, I've just exported it from IntelliJ IDEA, and uploaded it on the workupload.com cloud. The download link is: [link](https://workupload.com/start/rFfBThdwEGW). After unzipping and importing the project on IntelliJ, you may need to go File > Settings > Build, Execuction, Deployement > Build Tools > Gradle -> "Build and run using: **IntelliJ IDEA**" (instead of Gradle), in order to get it working. That was something I needed to do as well... Thanks for the help, @CrazyCoder. And, yes, the sound.wav file is inside the **resources** folder, properly marked. – Ricard Barnes May 15 '20 at 00:41

1 Answers1

1

The code you are using to load the resource as stream from the classpath is not correct.

You first get the URL of the resource with URL res = ClassLoader.getSystemResource("sound.wav");, then use getPath() method to convert it to String.

It works when the resource is not in the jar. But when it's in the jar, file URL becomes invalid and the code fails with FileNotFoundException.

Instead of that you need to change the code in MediaPlayer#playSound, replace

final AudioInputStream in = AudioSystem.getAudioInputStream(fileUrl);

with the following as a quick fix:

InputStream is = getClass().getResourceAsStream("/sound.wav");
final AudioInputStream in = AudioSystem.getAudioInputStream(new BufferedInputStream(is));

This will load the resource stream directly from the jar and the file will play.

See this answer for more details.

Your app will not run with Gradle because there is no support for GUI Designer in IntelliJ IDEA Gradle builds yet.

To build the jar I had to create an artifact manually and include the sound file there.

CrazyCoder
  • 389,263
  • 172
  • 990
  • 904