javajavafxmidigraalvm-native-imagegluonfx

GluonFX Native Image MIDI Issues


I have a JavaFX App where I use a MIDI device (Akai APC mini mk2) and I need to make a native image using GluonFX. Issue is concerning GluonFX native image and the use of MIDI.

Remember to read below Update 1 and 2.

The App is built in IntelliJ and this is MRE:

package org.example;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import javax.sound.midi.MidiDevice.Info;
import javax.sound.midi.MidiSystem;

public class FindMidiApp extends Application {

    @Override
    public void start(Stage primaryStage) {

        primaryStage.setTitle("Find Midi");
        ListView<String> listView = new ListView<>();
        VBox vbox = new VBox(10, listView);

        try {

            Info[] midiInfos = MidiSystem.getMidiDeviceInfo();

            for (Info info : midiInfos) {

                listView.getItems().add(String.format("%s - %s", info.getName(), info.getDescription()));
                
            }

        } catch (Exception e) {

            e.printStackTrace();

        }

        Scene scene = new Scene(vbox, 500, 300);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args) {

        launch(args);

    }

}

Using maven so this is the pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>ListMidi</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>23</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.gluonhq</groupId>
                <artifactId>gluonfx-maven-plugin</artifactId>
                <version>1.0.26</version>
                <configuration>
                    <mainClass>org.example.FindMidiApp</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.6</version>
                <configuration>
                    <mainClass>org.example.FindMidiApp</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

And this is the module-info.java:

module org.example {
    requires javafx.controls;
    requires java.desktop;
    exports org.example;
}

In IntelliJ the App works fine and it finds the APC Mini.

I have read and followed this: https://docs.gluonhq.com/#platforms_windows so now I want to turn the App into a native image with GluonFX so I open X64 native tool prompt and first browse to the folder with the project. Now I run (on computer a):

mvn clean

And then:

mvn gluonfx:runagent

App opens and finds APC mini. Now I run:

mvn gluonfx:build

Native image is built, and I run:

mvn gluonfx:nativerun

App opens and APC Mini is found and the same is going on if I open the native image directly from the folder, so far all is good.

This is the issue:

If I move the native image to another computer (computer b) and plugs the APC Mini into that computer only “Gervill – Software Midi Synthesizer” and “Real Time Sequencer – Software sequencer” are found. No APC Mini is found and not “Microsoft Midi Mapper – Windows Midi_mapper” and “Microsoft GS WaveTable Synth – Internal Software synthesizer” that was found on computer a.

If I copy the entire project to computer b, and runs it in IntelliJ then all the midi devices are found. All devices are also found on computer b if i run mvn glunfx:runagent but mvn gluonfx:nativerun (after gluonfx:build) only finds “Gervill – Software Midi Synthesizer” and “Real Time Sequencer – Software sequencer” and the same is happening if I run the generated native image directly from the folder.

So native image works on computer a and not (when moved) on computer b. And native image generated on computer b is not working working on computer b. And! when native image generated on computer b runs on computer a then it works so all in all native image works on computer a, no matter where it is generated.

I'm not sure this is related to the code or general Windows. Both computers have the same Windows version and updates. I have tested the APC Mini with a third party app, https://hautetechnique.com/midi/midiview/, and it finds the APC Mini on both computers.

Update 1:

When running below simple java from cmd in windows all devices are found on computer b (and computer a):

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;

public class Main {
    public static void main(String[] args) {
        
        MidiDevice.Info[] midiInfos = MidiSystem.getMidiDeviceInfo();
        for (MidiDevice.Info info : midiInfos) {
            System.out.println(info.getName() + " " + info.getDescription());
        }
    }
}

Update 2:

Okay, this is interesting: I found that having C:\yy\xx.jdks\openjdk-24\bin defined in the environment variable PATH on computer B allows the app to find all devices on computer B, even when using the native image generated on computer A.

So, the short answer is: The native image doesn't find any devices on computer B because Java is not defined in the PATH.

Is that how it is supposed to be?


Solution

  • This fixed it for me:

    I fixed the issue by placing jsound.dll in the same folder as the generated native image. I distribute the native image with Inno Setup so Inno Setup is doing the job distributing the .dll in to same folder as the .exe