-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem with native-image when trying to process MIDI IN events #10
Comments
We were able to reproduce the issues on Windows with a MIDI keyboard. To make it work it is possible to use native-image-agent to dump JNI and reflection methods used by the application to configuration files and then use the config files to generate the native image. Dump configuration files with native-image-agent:
Press MIDI keyboard keys.
Generate native image using JNI and Reflection configuration files:
|
Great thanks ! It works... Thanks to LIBERICA teams for the global efficient integration. |
Decision that AWT/Swing shared libraries are copied as is and are not included into a static native image on Windows has roots in AWT library static initialization order problem: AWT & Swing on Windows oracle/graal#3084 |
Given source code (hereafter) works well with JDK : MIDI output works and MIDI input event are caught and traced.
But after creating a native image, progam fails as soon as a MIDI keyboard key is pressed.
Source code:
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Transmitter;
public class HelloMidi {
/** Main method. /
public static void main(String[] args) {
System.err.println("HelloMidi");
//-Recover MIDI in & out
final Receiver midiOut=pickMidiOut("ESI M4U XT");
final Transmitter midiIn=pickMidiIn("MIDIIN4 (ESI M4U XT)");
//-Define what to do with events recovere for keyboard
midiIn.setReceiver(new Receiver() {
/* {@inheritdoc} /
@OverRide
public final void send(final MidiMessage message,final long timeStamp) {
//-A message has just been received
System.err.print("Message received->"+message.getLength()+" bytes");
for(final byte b:message.getMessage()) System.err.print(", "+Byte.toUnsignedInt(b));
System.err.println();
}
/* {@inheritdoc} /
@OverRide
public final void close() {
//-Nothing for this test !
}
});
assert(midiOut!=null);
try {
midiOut.send(new ShortMessage(144,60,120),-1);
Thread.sleep(1000);
midiOut.send(new ShortMessage(144,67,120),-1);
Thread.sleep(1000);
midiOut.send(new ShortMessage(144,72,120),-1);
Thread.sleep(20000);
//-Print accessible devics for information
for(final MidiDevice.Info mdi:MidiSystem.getMidiDeviceInfo()) System.err.println("Device '"+mdi.getName()+"':"+mdi);
} catch(final Exception e) {
//-Any problem
e.printStackTrace();
}
//-Exit
System.err.println("ByeMidi");
System.exit(0);
}
/* Check for requested MIDI OUT receiver. /
private static Receiver pickMidiOut(final String aName) {
//-Parse all devices
for(final MidiDevice.Info mdi:MidiSystem.getMidiDeviceInfo()) {
//-Check name
if(!mdi.getName().equals(aName)) continue;
//-Try in case there are errors
try {
//-Recover a MIDI device
final MidiDevice device=MidiSystem.getMidiDevice(mdi);
//-Try to open it
if(!device.isOpen()) device.open();
if(!device.isOpen()) continue;
//-Check receiver
final Receiver answer=device.getReceiver();
if(answer!=null) return(answer);
} catch(final Throwable e) {
//-Any problem
continue;
}
}
//-Return 'null' as none found
return(null);
}
/* Check for requested MIDI IN transmitter. */
private static Transmitter pickMidiIn(final String aName) {
//-Parse all devices
for(final MidiDevice.Info mdi:MidiSystem.getMidiDeviceInfo()) {
//-Check name
if(!mdi.getName().equals(aName)) continue;
//-Try in case there are errors
try {
//-Recover a MIDI device
final MidiDevice device=MidiSystem.getMidiDevice(mdi);
//-Try to open it
if(!device.isOpen()) device.open();
if(!device.isOpen()) continue;
//-Check receiver
final Transmitter answer=device.getTransmitter();
if(answer!=null) return(answer);
} catch(final Throwable e) {
//-Any problem
continue;
}
}
//-Return 'null' as none found
return(null);
}
}
This simple source code is self content and does not need anything else than standard JDK.
Using exe generated program, execption is thrown as soon as a MIDI key is pressed (or any other MIDI message)
HelloMidi
Exception in thread "Java Sound MidiInDevice Thread" java.lang.NoSuchMethodError: com.sun.media.sound.MidiInDevice.callbackShortMessage(IJ)V
at com.oracle.svm.jni.functions.JNIFunctions$Support.getMethodID(JNIFunctions.java:1247)
at com.oracle.svm.jni.functions.JNIFunctions$Support.getMethodID(JNIFunctions.java:1232)
at com.oracle.svm.jni.functions.JNIFunctions.GetMethodID(JNIFunctions.java:412)
at com.sun.media.sound.MidiInDevice.nGetMessages(MidiInDevice.java)
at com.sun.media.sound.MidiInDevice.run(MidiInDevice.java:127)
at java.lang.Thread.run(Thread.java:833)
at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:704)
at com.oracle.svm.core.windows.WindowsPlatformThreads.osThreadStartRoutine(WindowsPlatformThreads.java:143)
Operating system = windows + eclipse + jdk17
command line for native -> native-image.cmd --class-path c:\test\out HelloMidi
Thanks for your help
HelloMidi.zip
The text was updated successfully, but these errors were encountered: