Java.net.SocketException
beim Versuch, einen Multicast-Anbieter zu starten
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)
Dies wurde durch eine IPv6-Adresse verursacht, die von Java.net.NetworkInterface.getDefault()
zurückgegeben wurde. Ich bin auf einem Macbook und habe Wireless verwendet - p2p0 (für AirDrop verwendet) wurde als Standard-Netzwerkschnittstelle zurückgegeben, aber mein p2p0 hat nur einen IPv6-Eintrag ether
(gefunden durch Ausführen von ipconfig
).
Zwei Lösungen, die beide für mich funktionierten (ich bevorzuge die erste, weil sie funktioniert, egal ob Sie eine drahtgebundene oder eine drahtlose Verbindung verwenden)
-Djava.net.preferIPv4Stack=true
. Dies hat dazu geführt, dass Java.net.NetworkInterface.getDefault()
meine vboxnet0-Netzwerkschnittstelle zurückgibt. Sie sind sich nicht sicher, was Sie erhalten, wenn Sie keine Host-Only-VM ausführen.Eine kleine Abweichung von der akzeptierten Antwort: Sie können Ihrem Java-Code auch die folgende Codezeile hinzufügen:
System.setProperty("Java.net.preferIPv4Stack", "true");
Sie müssen bestimmte Konfigurationen zu Java VM hinzufügen, bevor Sie einem Multicast-Socket auf einer beliebigen Maschine beitreten können.
Fügen Sie zunächst diese Zeile hinzu, bevor Sie eine Verbindung herstellen, um sicherzustellen, dass Sie nur IPv4-Adressen erhalten:
System.setProperty("Java.net.preferIPv4Stack", "true");
In den meisten Fällen verfügt Ihr Computer über mehrere Netzwerkschnittstellen. Daher müssen Sie die richtige auswählen:
Enumeration e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
NetworkInterface n = (NetworkInterface) e.nextElement();
Enumeration ee = n.getInetAddresses();
while (ee.hasMoreElements()) {
InetAddress i = (InetAddress) ee.nextElement();
if (i.isSiteLocalAddress() && !i.isAnyLocalAddress() && !i.isLinkLocalAddress()
&& !i.isLoopbackAddress() && !i.isMulticastAddress()) {
socket.setNetworkInterface(NetworkInterface.getByName(n.getName()));
}
}
}
In meinem Fall hatte ich gerade damit begonnen, ein VPN für ein Netzwerk zu verwenden, für das eine Authentifizierung erforderlich war. Meine App wurde gestartet und konnte über die Pipeline eine Verbindung zu ihren Datenbanken herstellen, aber meine Konfiguration für den verteilten Cache mit der IP 230.0.0.1 in ehcach.xml war die Ursache. In der Produktion war alles in Ordnung, lokal würde es einfach fehlschlagen und zu einer anderen Strategie zurückkehren, aber über das VPN wurden die Multicast-Anforderungen mit einer Authentifizierungsherausforderung erfüllt, und dieser Fehler war das Ergebnis. Ich habe nur eine kurzfristige Korrektur benötigt, also deaktiviere ich in diesen Umgebungen die Ehcache-Multicast-Konfiguration und die Dinge sind wieder normal.
Dies war die beleidigende Zeile in ehcache.xml
, die einfach auskommentiert wurde
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446, timeToLive=32"
/>