executable jar + audioclips

374 views Asked by At

I've been getting this exception when running the app from an executable jar:

java.lang.UnsupportedOperationException: Unsupported protocol "rsrc"
       at com.sun.media.jfxmedia.locator.Locator.<init>(Locator.java:233)
    at com.sun.media.jfxmediaimpl.NativeMediaAudioClip.<init>(NativeMediaAudioClip.java:53)
    at com.sun.media.jfxmediaimpl.NativeMediaAudioClip.load(NativeMediaAudioClip.java:63)
    at com.sun.media.jfxmediaimpl.AudioClipProvider.load(AudioClipProvider.java:66)
    at com.sun.media.jfxmedia.AudioClip.load(AudioClip.java:135)
    at javafx.scene.media.AudioClip.<init>(AudioClip.java:83)
    at com.aqua.snakesandladders.view.gamepieces.Token.<init>(Token.java:70)"

here's Token.java:70, which is the cause of this:

AudioClip bounceSound = new AudioClip(getClass().getResource("/sounds/bounce.wav").toExternalForm());

"bounce.wav" is located in "resources" source folder @ "sounds" subfolder.

Running the app in eclipse throws no exception @ this point + plays the AudioClip when needed.

Help! :(

1

There are 1 answers

0
Tony On

Source

The following is the code that throws Exception:

this.scheme = this.scheme.toLowerCase();
if (this.scheme.equals("jar")) {
  URI subURI = new URI(this.uriString.substring(4));
  this.protocol = subURI.getScheme();
  if (this.protocol == null) {
    throw new IllegalArgumentException("uri.getScheme() == null!");
  }

  this.protocol = this.protocol.toLowerCase();
} else {
  this.protocol = this.scheme;
}

if (!this.protocol.equals("file") && !this.protocol.equals("http")) {
  throw new UnsupportedOperationException("Unsupported protocol \"" + this.protocol + "\"");
} else {
  if (this.protocol.equals("http")) {
    this.canBlock = true;
  }

  this.uri = uri;
}

If you print your uri here you can see something like:

rsrc:foo.bar.Main

Which is a invalid uri as javafx told you.

Manifest

So why you uri is invlaid?

If you open your Manifest file, you will find some entries which eclipse added, likeļ¼š

...
Rsrc-Class-Path: ./
Rsrc-Main-Class: net.xxx.main.Main
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader

and here is where the rsrc comes from.

Advice

  • Update your manifest file to be like original manifest, i.e. remove rsrc started entry and change main class to your class;
  • Not use eclipse to package your jar, using tools like maven, gradle
  • Use Intellij :)