0

I want to be able to play sound from mp3 files for which I saw posts recommending the usage of JavaFX. I implemented the MediaPlayer and initialized the JFXPanel and in eclipse, everything works lovely.

Yet when I export to a runnable jar, and try running the program, I get the following error message: java.lang.NoClassDefFoundError: javafx/scene/media/MediaException.

I presume this is from the exclusion of JavaFX in the newer JRE versions (which I came across during my search to a solution). My main question is how do I ship the jar with JavaFX? Do I have to include a jar, and if yes, where do I get it? Because eclipse doesn't seem to package JavaFX into my runnable if I'm not mistaken.

Here an example which, for me, already triggers this behavior:

// This would throw a java.lang.NoClassDefFoundError for the JFXPanel but is effectively the same problem
public class Test extends Application
{
    public static void main(String[] Args)
    {
        launch(Args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        StackPane root = new StackPane();

        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

Thank you for your help!

2 Answers2

1

JavaFx was removed into JDK> = 11 and now is a separate project opensurse [openjfx] (https://openjfx.io/). And now it is to be made more difficult to create a version of the application javafx runnable everywhere, but it is a continuous evolution and I think that this is good documentation [doc-image-live] (https://openjfx.io/openjfx-docs/#modular).

I had a problem simile when I used for the developing the JDK 1.8 but in my version java system is openjdk11, I think this is the same case.

Your example is wrong because not is a JavaFX application. The JavaFX application must extend the javafx.application.Application and in the main call the method launch, this method will call the method start inherited from Application.

This is a simple example of the Oracle

public class HelloWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

ps: When you speak the javafx, you must add the java version because we don't know your java version

vincenzopalazzo
  • 1,487
  • 2
  • 7
  • 35
  • 1
    So to sum it up, you effectively have to download the jre from openjfx's official website and add the required jars from there to your eclipse build path. Quite annoying but thank you very much! –  Jul 02 '19 at 09:06
  • Yes, you must bring it back the submodule for run javafx, good work – vincenzopalazzo Jul 02 '19 at 09:09
  • One final question, if you don't mind. Can I initialize the JavaFX toolkit with the media jar only or do I have to use an eg. JFXPanel? Just wondering if I can reduce the classes I need to export into the jar. –  Jul 02 '19 at 09:12
  • The Application class with main in the JavaFX must be extend the Application and call the method _launch_, look this example https://docs.oracle.com/javafx/2/get_started/hello_world.htm, for minimize the class in the jar is a good guideline for java code but for code in general but this depends on your code structure. Ps: please you update the example in the your post with the guideline javafx framework – vincenzopalazzo Jul 02 '19 at 09:29
  • haha, I now have two more problems: first, what do you mean by guideline javafx framework? I'm not quite sure what you want me to do :/. Second the Graphics Device initialization fails when using the new JFXPanel on mac. Is there a way to use the old javafx media player and JFXPanel which do not require further graphics libraries? Cheers! –  Jul 02 '19 at 09:49
  • The JavaFX application must extend a javafx.application.Application and call the method _launch_ and write the code on the method _start_. Your example not run because it isn't an application JavaFX For your second problem I don't know the problem because I don't know your code. For more information on the JavaFX application look the example on the internet or my previous link and I have updated my answer with an example – vincenzopalazzo Jul 02 '19 at 09:58
  • Interesting... in previous versions you were able to initialize the JFX functions by invoking a new JFXPanel. That is not a thing any more? Pretty annoying... –  Jul 02 '19 at 10:15
  • Mh I don't know if in the previous version is possible to initialize the JFXPanel without the guideline JavaFX because I used always the guidelines. I don't know the answer because I preferer using swing for the Java desktop app, I 'am a contributor for [materal-ui-swing](https://github.com/atarw/material-ui-swing) and I love the modularization of the swing and I preferer used it – vincenzopalazzo Jul 02 '19 at 10:25
  • Yeah, I also like javax.swing.JFrame a lot more. Its just that JFX has a quite good sound api which swing doesn't... I'm trying to just extract the previous version of jfx from the 9.0.4 SE and use these jars as a starting point because my entire app is already using JFrame and I really don't want to go through the hassle of changing that –  Jul 02 '19 at 10:32
0

An alternative path, if you prefer to not use JavaFX, would be to make use of the libraries that originated from JavaZOOM for the task of reading the mp3 files. I am seeing many offerings on github that have been derived from this source, for example, https://github.com/goxr3plus/java-sound-libraries But I have not made use of this particular library myself.

My preference has been to combine JavaFX for GUI with javax.audio.sampled, and a library I built that relies on java.sound.sampled.SourceDataLine for output. But I never bothered to implement reading mp3s. I tend to take the ogg/vorbis route when using compressed audio resources.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41