Andrew Wilken
Andrew Wilken

Reputation: 55

Program works in Eclipse but when I export to runnable JAR it doesnt. FileNotFoundException

I tried to make a runnable JAR, but for some reason I couldn't get my game to play. I did some research and ran it through my command prompt to try to find the error and I got this below. So obviously I know the issue I just need to fix it. I have the audio file in my res folder which is in my src. So if it is already in the program I can't figure out why I would get this error. Thoughts?

Exception in thread "main" java.lang.NullPointerException
        at java.base/java.util.Objects.requireNonNull(Unknown Source)
        at java.desktop/javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at builder.AudioPlayer.playMenuSound(AudioPlayer.java:20)
        at builder.Game.<init>(Game.java:56)
        at builder.Game.main(Game.java:61)
package builder;

import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class AudioPlayer {

    private static Clip play;

    public static void playMenuSound()
    {
        try {
            //AudioInputStream menuSound = AudioSystem.getAudioInputStream(new File("src/res/introSong.wav")); //Take in audio from res folder
            AudioInputStream menuSound = AudioSystem.getAudioInputStream(AudioPlayer.class.getClassLoader().getResourceAsStream("introSong.wav"));
            play = AudioSystem.getClip(); //
            play.open(menuSound); //Play the sound
            FloatControl volume = (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN); //Get control of volume
            volume.setValue(1.0f); //0.0 - 1.0 volume
            play.loop(Clip.LOOP_CONTINUOUSLY); //Loop once clip is over
        }catch (LineUnavailableException | IOException | UnsupportedAudioFileException e){
            e.printStackTrace();
        }
    }

    public static void playGameSound()
    {
        try {
            //AudioInputStream gameSound = AudioSystem.getAudioInputStream(new File("src/res/inGame.wav")); //Take in audio from res folder
            AudioInputStream gameSound = AudioSystem.getAudioInputStream(AudioPlayer.class.getClassLoader().getResourceAsStream("inGame.wav"));
            play = AudioSystem.getClip(); //
            play.open(gameSound); //Play the sound
            FloatControl volume = (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN); //Get control of volume
            volume.setValue(0.5f); //0.0 - 1.0 volume
            play.loop(Clip.LOOP_CONTINUOUSLY); //Loop once clip is over
        }catch (LineUnavailableException | IOException | UnsupportedAudioFileException e){
            e.printStackTrace();
        }
    }

    public static void stopMusic()
    {
        play.close(); //Stop music
    }
}

Upvotes: 0

Views: 64

Answers (2)

Phil Freihofner
Phil Freihofner

Reputation: 7910

I have had success with the following form for setting up Clips. Perhaps it will work for you.

    URL url = this.getClass().getResource("audio/" + filename);
    AudioInputStream ais = AudioSystem.getAudioInputStream(url);
    DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
    Clip clip = (Clip) AudioSystem.getLine(info);
    clip.open(ais);

The method getResource returns a URL. The method getResourceAsStream returns an InputStream. A URL works as a way to address a file within a jar.

In this example, the file in which the code resides is a parent to the folder "/audio" and the audio resource is in the "/audio" folder.

The following form works for me if you desire to call the loader as a static method.

    URL url = AudioPlayer.class.getResource("audio/" + filename);

Upvotes: 0

Safeer Ansari
Safeer Ansari

Reputation: 790

The problem in your code is where you're trying to instantiate your file with a new reference, here:

AudioInputStream gameSound = AudioSystem.getAudioInputStream(new File("src/res/inGame.wav"));

Instead of doing that, you need to get your file as a resource using a ClassLoader, since it is located inside the resource (res) folder.

Here is how your code should look like:

AudioInputStream gameSound = AudioSystem.getAudioInputStream(AudioPlayer.class.getClassLoader().getResourceAsStream("inGame.wav"));

Same should be done in with your introSong.wav in the playMenuSound() method. The code should look something like

AudioInputStream gameSound = AudioSystem.getAudioInputStream(AudioPlayer.class.getClassLoader().getResourceAsStream("introSong.wav"));

I really hope this solves your problem.

Upvotes: 2

Related Questions