-
Notifications
You must be signed in to change notification settings - Fork 477
This fails with the following exception:
SEVERE: failed setting ip_ttl java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.jgroups.protocols.UDP.setTimeToLive(UDP.java:339) at org.jgroups.protocols.UDP.createSockets(UDP.java:368) at org.jgroups.protocols.UDP.start(UDP.java:270) at org.jgroups.stack.ProtocolStack.startStack(ProtocolStack.java:965) ... Caused by: java.io.IOException: Method not implemented! at java.net.DualStackPlainDatagramSocketImpl.setTimeToLive(Unknown Source) ... 69 more
The problem is that the default DatagramSocketImpl
chosen (after Windows Vista) is DualStackPlainDatagramSocketImpl
, which doesn’t implement setTimeToLive()
. This means that UDP.ip_ttl
cannot be set and is always 1.
The other implementation, TwoStacksPlainDatagramSocketImpl
, does implement setTimeToLive()
and should be used. This can be done in 3 ways:
-
Force use of IPv4:
-Djava.net.preferIPv4Stack=true
-
Use the
impl.prefix
system property to pick theTwoStacksPlainDatagramSocketImpl
implementation, e.g.-Dimpl.prefix=TwoStacksPlain
-
Set the
DatagramSocketFactoryImpl
programmatically:
public class bla2 { protected static String socket_impl_name="java.net.TwoStacksPlainDatagramSocketImpl"; protected static Class<?> clazz; protected static Constructor<?> ctor; static { try { clazz=Class.forName(socket_impl_name); ctor=clazz.getDeclaredConstructors()[0]; ctor.setAccessible(true); } catch(ClassNotFoundException ex) { throw new RuntimeException(ex); } } public static void main(String[] args) throws Exception { DatagramSocket.setDatagramSocketImplFactory(new MyDatagramSocketFactory()); DatagramSocket sock=new DatagramSocket(7500); } protected static class MyDatagramSocketFactory implements DatagramSocketImplFactory { public MyDatagramSocketFactory() { } public DatagramSocketImpl createDatagramSocketImpl() { try { return (DatagramSocketImpl)ctor.newInstance(); } catch(Exception ex) { throw new RuntimeException(ex); } } } }
This problem has been fixed in https://issues.jboss.org/browse/JGRP-1970: instead of using a DatagramSocket
to send multicasts, I reverted to using a MulticastSocket
which supports setTimeToLive()
by using the TwoStacksPlainDatagramSocketImpl
.