Skip to content
Bela Ban edited this page Oct 22, 2015 · 7 revisions

Frequently asked questions

Windows issue with setting UDP.ip_ttl in IPv6 (read the update at the end !)

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:

  1. Force use of IPv4: -Djava.net.preferIPv4Stack=true

  2. Use the impl.prefix system property to pick the TwoStacksPlainDatagramSocketImpl implementation, e.g. -Dimpl.prefix=TwoStacksPlain

  3. 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);
            }
        }
    }
}

Update: fixed in JGroups 3.6.7

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.