Получение "Невозможно назначить запрошенный адрес" java.net.SocketException с использованием многоадресной рассылки Ehcache

Получение java.net.SocketException при попытке запустить многоадресный провайдер:

2013-09-11 11:45:44,204 [main] ERROR net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider: Error starting heartbeat. Error was: Can't assign requested address
java.net.SocketException: Can't assign requested address
at java.net.PlainDatagramSocketImpl.join(Native Method)
at java.net.AbstractPlainDatagramSocketImpl.join(AbstractPlainDatagramSocketImpl.java:178)
at java.net.MulticastSocket.joinGroup(MulticastSocket.java:319)
at net.sf.ehcache.distribution.MulticastKeepaliveHeartbeatReceiver.init(MulticastKeepaliveHeartbeatReceiver.java:88)
at net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:95)

Ответ 1

Это было вызвано возвратом IPv6-адреса из java.net.NetworkInterface.getDefault(). Я нахожусь в Macbook и использую wireless - p2p0 (используется для AirDrop) был возвращен как сетевой интерфейс по умолчанию, но мой p2p0 имеет только запись IPv6 ether (найденная при запуске ipconfig).

Два решения, оба из которых работали для меня (я предпочитаю первый, потому что он работает независимо от того, используете ли вы проводное или беспроводное соединение)

  1. Запустите JVM с помощью -Djava.net.preferIPv4Stack=true. Это вызвало java.net.NetworkInterface.getDefault() чтобы вернуть мой сетевой интерфейс vboxnet0 - не уверен, что вы получите, если не используете виртуальную машину только для хоста.
  2. Отключите беспроводную связь и используйте проводное соединение

Ответ 2

Небольшое отклонение от принятого ответа: вы также можете добавить следующую строку кода в код Java:

System.setProperty("java.net.preferIPv4Stack", "true");

Ответ 3

Вам необходимо добавить определенные конфигурации в Java VM, прежде чем вы сможете присоединить сокет Multicast на любом компьютере.

Сначала добавьте эту строку, прежде чем пытаться подключиться, чтобы убедиться, что вы получите только адреса IPv4:

System.setProperty("java.net.preferIPv4Stack", "true");

В большинстве случаев ваш компьютер имеет более одного сетевого интерфейса, поэтому вам нужно выбрать правильный:

Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
    NetworkInterface networkInterface = networkInterfaces.nextElement();
    Enumeration<InetAddress> addressesFromNetworkInterface = networkInterface.getInetAddresses();
    while (addressesFromNetworkInterface.hasMoreElements()) {
        InetAddress inetAddress = addressesFromNetworkInterface.nextElement();
        if (inetAddress.isSiteLocalAddress()
                && !inetAddress.isAnyLocalAddress()
                && !inetAddress.isLinkLocalAddress()
                && !inetAddress.isLoopbackAddress()
                && !inetAddress.isMulticastAddress()) {
            socket.setNetworkInterface(NetworkInterface.getByName(networkInterface.getName()));
        }
    }
}

Ответ 4

В моем случае я только начал использовать VPN в сети, требующей аутентификации. Мое приложение запустится и сможет подключиться к своим базам данных через канал, но моя конфигурация для распределенного кеша с использованием IP 230.0.0.1 в ehcach.xml была причиной. В производстве все было хорошо, локально он просто терпел неудачу и откатывался к другой стратегии, но через VPN запросы многоадресной рассылки удовлетворялись вызовом аутентификации, и эта ошибка была результатом. Мне потребовалось только короткое исправление, поэтому в этих средах я отключу конфигурацию многоадресной рассылки ehcache, и все вернулось в нормальное состояние.

Это была оскорбительная строка в ehcache.xml которая была просто прокомментирована

<cacheManagerPeerProviderFactory
  class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
  properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446, timeToLive=32"
/>