Duplicate :
|
|
Relates :
|
|
Relates :
|
FULL PRODUCT VERSION : java version "1.8.0_25" Java(TM) SE Runtime Environment (build 1.8.0_25-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) ADDITIONAL OS VERSION INFORMATION : Linux pclt-henjoh 3.16.0-25-generic #33-Ubuntu SMP Tue Nov 4 12:06:54 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux EXTRA RELEVANT SYSTEM CONFIGURATION : lksctp-tools 1.0.16 A DESCRIPTION OF THE PROBLEM : JVM exits with InternalError when calling SctpMultiChannel.receive If a remote address which I am trying to send a packet to is down / not listening, I get a "java.lang.InternalError: should not reach here" error in SctpMultiChannel.receive, if the payload of my SctpMultiChannel.send call was 101 bytes or more. If I use a payload of 100 bytes or less, I get a sun.nio.ch.sctp.SendFailed notification instead, which seems more correct and is what I would expect. This behaviour was introduced in Java 1.8.0_20, and does not exist in 1.8.0_11 and earlier. (It also exists in Java 1.7.0_60 and later but not in 1.7.0_55 and earlier.) REGRESSION. Last worked in version 8u11 ADDITIONAL REGRESSION INFORMATION: java version "1.8.0_11" Java(TM) SE Runtime Environment (build 1.8.0_11-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode) STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Run provided test program with Java 1.8.0_25 to reproduce the problem. Run provided test program with Java 1.8.0_11 or earlier to see that it worked before. The test program first shows that 100 bytes works and then that 101 bytes fails: 1. SctpMultiChannel.send(ByteBuffer.allocate(100 bytes), remoteAddressNotListening); 2. SctpMultiChannel.receive( notificationhandler ) 3. SctpMultiChannel.receive( notificationhandler) 4. SctpMultiChannel.send(ByteBuffer.allocate(101 bytes), remoteAddressNotListening); 5. SctpMultiChannel.receive( notificationhandler ) 6. SctpMultiChannel.receive( notificationhandler ) EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - 1. SctpMultiChannel.send(ByteBuffer.allocate(100 bytes), remoteAddressNotListening); 2. SctpMultiChannel.receive( NotificationHandler AssociationChangeEvent CANT_START ) 3. SctpMultiChannel.receive( NotificationHandler SendFailed ) 4. SctpMultiChannel.send(ByteBuffer.allocate(101 bytes), remoteAddressNotListening); 5. SctpMultiChannel.receive( NotificationHandler AssociationChangeEvent CANT_START ) 6. SctpMultiChannel.receive( NotificationHandler SendFailed ) ACTUAL - 1. SctpMultiChannel.send(ByteBuffer.allocate(100 bytes), remoteAddressNotListening); 2. SctpMultiChannel.receive( NotificationHandler AssociationChangeEvent CANT_START ) 3. SctpMultiChannel.receive( NotificationHandler SendFailed ) 4. SctpMultiChannel.send(ByteBuffer.allocate(101 bytes), remoteAddressNotListening); 5. SctpMultiChannel.receive( NotificationHandler AssociationChangeEvent CANT_START ) 6. SctpMultiChannel.receive( ) "java.lang.InternalError: should not reach here" ERROR MESSAGES/STACK TRACES THAT OCCUR : Exception in thread "main" java.lang.InternalError: should not reach here at sun.nio.ch.sctp.SctpChannelImpl.receive0(Native Method) at sun.nio.ch.sctp.SctpMultiChannelImpl.receive0(SctpMultiChannelImpl.java:978) at sun.nio.ch.sctp.SctpMultiChannelImpl.receiveIntoNativeBuffer(SctpMultiChannelImpl.java:582) at sun.nio.ch.sctp.SctpMultiChannelImpl.receive(SctpMultiChannelImpl.java:566) at sun.nio.ch.sctp.SctpMultiChannelImpl.receive(SctpMultiChannelImpl.java:496) at Main.send(Main.java:96) at Main.main(Main.java:61) REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- import com.sun.nio.sctp.HandlerResult; import com.sun.nio.sctp.MessageInfo; import com.sun.nio.sctp.Notification; import com.sun.nio.sctp.NotificationHandler; import com.sun.nio.sctp.SctpMultiChannel; import com.sun.nio.sctp.SctpStandardSocketOptions; import com.sun.nio.sctp.SctpStandardSocketOptions.InitMaxStreams; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Date; import java.util.List; /** * This test tries to connect to a remote address, which is down, using the SCTP protocol. * It uses SctpMultiChannel to initiate an implicit association by sending a packet to the remote side. * * On Linux, the packet "is sent" and I can use my NotificationHandler to receive CANT_START and SendFailed notifications. * On Solaris, the SctpMultiChannel.send() throws a java.net.ConnectException: Connection refused. * * It seems the size of this packet matters in newer Java versions than 1.8u11/1.7u55. * If I use 1.8u20/1.7u60, or later, I cannot use more than 100 bytes in the initial packet * without getting an InternalError instead of a SendFailed notification. * */ public class Main { static SocketAddress localSocketAddress = new InetSocketAddress("127.0.0.1", 2000); static SocketAddress remoteSocketAddress = new InetSocketAddress("127.0.0.1", 3000); public static void main(final String[] args) { if(args.length == 4) { try { localSocketAddress = new InetSocketAddress(args[0], Integer.parseInt(args[1])); remoteSocketAddress = new InetSocketAddress(args[2], Integer.parseInt(args[3])); } catch(Exception e) { e.printStackTrace(); } } else { System.out.println("Usage: java Main <localip> <localport> <remoteip> <remoteport>"); } System.out.println("Using local address: " + localSocketAddress); System.out.println("Using remote address: " + remoteSocketAddress); System.out.println("Note, remote address should not be up"); printSystemInfo(); final Main main = new Main(); // This will work main.send(100); // This will fail, // on Linux with newer Java than 1.8u11/1.7u55 main.send(101); } public void send(final int sendBufferSize) { System.out.println("==== Trying with " + sendBufferSize + " byte send buffer ===="); try (final SctpMultiChannel sctpMultiChannel = SctpMultiChannel.open()) { sctpMultiChannel.setOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS, InitMaxStreams.create(1, 1), null); sctpMultiChannel.bind(localSocketAddress); final MessageInfo messageInfo = MessageInfo.createOutgoing(remoteSocketAddress, 0); System.out.println("Sending connection attempt to " + remoteSocketAddress.toString()); final int sent = sctpMultiChannel.send(ByteBuffer.allocate(sendBufferSize), messageInfo); System.out.println("Sent " + sent); final NotificationHandler notificationHandler = new NotificationHandler<Object>() { @Override public HandlerResult handleNotification(Notification notification, Object o) { System.out.println("Notification: " + notification); return HandlerResult.RETURN; } }; final ByteBuffer receiveByteBuffer = ByteBuffer.allocate(1024); receiveByteBuffer.clear(); System.out.println("First receive on SctpMultiChannel"); final MessageInfo receivedMessageInfo1 = sctpMultiChannel.receive(receiveByteBuffer, null, notificationHandler); receiveByteBuffer.clear(); System.out.println("Second receive on SctpMultiChannel"); final MessageInfo receivedMessageInfo2 = sctpMultiChannel.receive(receiveByteBuffer, null, notificationHandler); System.out.println("No InternalError, success!\n"); } catch (final Exception e) { e.printStackTrace(); } } private static void printSystemInfo() { final List<String> properties = Arrays.asList( "os.name", "os.arch", "os.version", "java.runtime.version", "java.vm.specification.vendor"); for(final String property : properties) { System.out.println(property + ": " + System.getProperty(property)); } } } ---------- END SOURCE ----------
|