FAQ - belaban/JGroups GitHub Wiki
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.prefixsystem property to pick theTwoStacksPlainDatagramSocketImplimplementation, e.g.-Dimpl.prefix=TwoStacksPlain -
Set the
DatagramSocketFactoryImplprogrammatically:
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.