-
Bug
-
Resolution: Fixed
-
P3
-
8, 11, 13, 14, 15
-
b24
-
x86_64
-
windows_10
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8257200 | 11.0.11-oracle | Sergey Bylokhov | P3 | Resolved | Fixed | b01 |
JDK-8258998 | 11.0.11 | Sergey Bylokhov | P3 | Resolved | Fixed | b01 |
JDK-8272495 | openjdk8u312 | Sergey Bylokhov | P3 | Resolved | Fixed | b03 |
ADDITIONAL SYSTEM INFORMATION :
All Windows and Linux installations I have tested on.
A DESCRIPTION OF THE PROBLEM :
Some synthesizers (notably the Casio CZ series and the Yamaha TG33, SY22, and SY35) require that you send a sysex message not all at once but piecemeal, separated by delays. The standard Java sysex class only sends whole messages at a time, but it is easy -- and appropriate -- to create a message class which allows you to send arbitrary data as needed. However if you use this class to send a single 0xF7 (the value which indicates the end of a sysex message), the virtual machine will bomb hard in Windows and in Linux. This is not the case on the Mac because (1) MacOS Java is broken with regard to sysex in the first place and (2) everyone on the Mac who does MIDI Java uses the superior CoreMidi4J library anyway, and this library has no problem with 0xF7.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a subclass of javax.sound.midi.MidiMessage which permits you to send arbitrary bytes in the stream.
2. Use this message subclass to send a single 0xF7.
3. All Windows implementations and all current Linux implementations will fail.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
An 0xF7 is sent out the MIDI stream.
ACTUAL -
VM fails with a report of accessing deallocated memory.
---------- BEGIN SOURCE ----------
import javax.sound.midi.*;
import java.util.*;
public class Send
{
public static class RawMidiMessage extends MidiMessage
{
public Object clone()
{
return new RawMidiMessage(getMessage());
}
public int getStatus() { return 0xF0; } // not that this really matters
public RawMidiMessage(byte[] data)
{
super(data.clone());
}
}
public static void main(String[] args) throws Exception
{
MidiDevice.Info[] infos;
infos = MidiSystem.getMidiDeviceInfo();
for(int i = 0; i < infos.length; i++)
{
System.err.println("" + i + "\t" + infos[i]);
}
int dev = 4; // For me, that's MIDI Monitor
MidiDevice device = MidiSystem.getMidiDevice(infos[dev]); // or pick an appropriate device
System.err.println("Sending to " + device + " ( " + infos[dev] + ")");
if (!device.isOpen()) device.open();
Receiver r = device.getReceiver();
System.err.println("note on");
r.send(new ShortMessage(ShortMessage.NOTE_ON, 5, 5), -1);
System.err.println("sysex");
r.send(new SysexMessage(new byte[] { (byte)0xF0, 0x0, 0x03, 0x04, (byte)0xF7 }, 5), -1);
System.err.println("raw 1");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 2");
r.send(new RawMidiMessage(new byte[] { (byte)0x09, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 3");
r.send(new RawMidiMessage(new byte[] { (byte)0xF0, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 4");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 5");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, (byte)0xF7 }), -1);
System.err.println("raw 6");
r.send(new RawMidiMessage(new byte[] { (byte)0xF0, 0x02, 0x03, 0x04 }), -1);
System.err.println("sleep");
Thread.currentThread().sleep(1000);
System.err.println("raw 7");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, 0x04 }), -1);
System.err.println("sleep");
Thread.currentThread().sleep(1000);
System.err.println("raw 8");
r.send(new RawMidiMessage(new byte[] { (byte) (byte)0xF7 }), -1);
System.err.println("note off");
r.send(new ShortMessage(ShortMessage.NOTE_OFF, 5, 5), -1);
System.err.println("done, should quit");
}
}
---------- END SOURCE ----------
FREQUENCY : always
All Windows and Linux installations I have tested on.
A DESCRIPTION OF THE PROBLEM :
Some synthesizers (notably the Casio CZ series and the Yamaha TG33, SY22, and SY35) require that you send a sysex message not all at once but piecemeal, separated by delays. The standard Java sysex class only sends whole messages at a time, but it is easy -- and appropriate -- to create a message class which allows you to send arbitrary data as needed. However if you use this class to send a single 0xF7 (the value which indicates the end of a sysex message), the virtual machine will bomb hard in Windows and in Linux. This is not the case on the Mac because (1) MacOS Java is broken with regard to sysex in the first place and (2) everyone on the Mac who does MIDI Java uses the superior CoreMidi4J library anyway, and this library has no problem with 0xF7.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a subclass of javax.sound.midi.MidiMessage which permits you to send arbitrary bytes in the stream.
2. Use this message subclass to send a single 0xF7.
3. All Windows implementations and all current Linux implementations will fail.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
An 0xF7 is sent out the MIDI stream.
ACTUAL -
VM fails with a report of accessing deallocated memory.
---------- BEGIN SOURCE ----------
import javax.sound.midi.*;
import java.util.*;
public class Send
{
public static class RawMidiMessage extends MidiMessage
{
public Object clone()
{
return new RawMidiMessage(getMessage());
}
public int getStatus() { return 0xF0; } // not that this really matters
public RawMidiMessage(byte[] data)
{
super(data.clone());
}
}
public static void main(String[] args) throws Exception
{
MidiDevice.Info[] infos;
infos = MidiSystem.getMidiDeviceInfo();
for(int i = 0; i < infos.length; i++)
{
System.err.println("" + i + "\t" + infos[i]);
}
int dev = 4; // For me, that's MIDI Monitor
MidiDevice device = MidiSystem.getMidiDevice(infos[dev]); // or pick an appropriate device
System.err.println("Sending to " + device + " ( " + infos[dev] + ")");
if (!device.isOpen()) device.open();
Receiver r = device.getReceiver();
System.err.println("note on");
r.send(new ShortMessage(ShortMessage.NOTE_ON, 5, 5), -1);
System.err.println("sysex");
r.send(new SysexMessage(new byte[] { (byte)0xF0, 0x0, 0x03, 0x04, (byte)0xF7 }, 5), -1);
System.err.println("raw 1");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 2");
r.send(new RawMidiMessage(new byte[] { (byte)0x09, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 3");
r.send(new RawMidiMessage(new byte[] { (byte)0xF0, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 4");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, 0x04 }), -1);
System.err.println("raw 5");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, (byte)0xF7 }), -1);
System.err.println("raw 6");
r.send(new RawMidiMessage(new byte[] { (byte)0xF0, 0x02, 0x03, 0x04 }), -1);
System.err.println("sleep");
Thread.currentThread().sleep(1000);
System.err.println("raw 7");
r.send(new RawMidiMessage(new byte[] { (byte)0x02, 0x02, 0x03, 0x04 }), -1);
System.err.println("sleep");
Thread.currentThread().sleep(1000);
System.err.println("raw 8");
r.send(new RawMidiMessage(new byte[] { (byte) (byte)0xF7 }), -1);
System.err.println("note off");
r.send(new ShortMessage(ShortMessage.NOTE_OFF, 5, 5), -1);
System.err.println("done, should quit");
}
}
---------- END SOURCE ----------
FREQUENCY : always
- backported by
-
JDK-8257200 Java MIDI fails with a dereferenced memory error when asked to send a raw 0xF7
- Resolved
-
JDK-8258998 Java MIDI fails with a dereferenced memory error when asked to send a raw 0xF7
- Resolved
-
JDK-8272495 Java MIDI fails with a dereferenced memory error when asked to send a raw 0xF7
- Resolved
- relates to
-
JDK-8301310 The SendRawSysexMessage test may cause a JVM crash
- Resolved
(1 links to)