Obtenir Java.net.SocketException
lorsque vous essayez de démarrer un fournisseur de multidiffusion:
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)
Cela était dû à une adresse IPv6 renvoyée par Java.net.NetworkInterface.getDefault()
. Je suis sur un Macbook et j'utilisais sans fil - p2p0 (utilisé pour AirDrop) a été renvoyé comme interface réseau par défaut, mais mon p2p0 a uniquement une entrée IPv6 ether
(trouvée en exécutant ipconfig
).
Deux solutions, qui ont toutes deux fonctionné pour moi (je préfère la première parce que cela fonctionne que vous utilisiez une connexion filaire ou sans fil)
-Djava.net.preferIPv4Stack=true
. Cela a amené Java.net.NetworkInterface.getDefault()
à renvoyer mon interface réseau vboxnet0 - vous ne savez pas exactement ce que vous obtiendrez si vous n'exécutez pas de machine virtuelle réservée à l'hôte.Une légère variation de la réponse acceptée: vous pouvez également ajouter la ligne de code suivante à votre code Java:
System.setProperty("Java.net.preferIPv4Stack", "true");
Vous devez ajouter certaines configurations à Java VM avant de pouvoir rejoindre un socket de multidiffusion sur n’importe quel ordinateur.
Ajoutez d’abord cette ligne avant d’essayer toute connexion pour vous assurer que vous n’obtiendrez que les adresses IPv4:
System.setProperty("Java.net.preferIPv4Stack", "true");
Dans la plupart des cas, votre ordinateur possède plusieurs interfaces réseau. Vous devez donc choisir celle qui convient:
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()));
}
}
}
Dans mon cas, je venais juste de commencer à utiliser un VPN sur un réseau qui nécessitait une authentification. Mon application pouvait démarrer et pouvait se connecter à ses bases de données via le tuyau, mais ma configuration pour le cache distribué utilisant l'IP 230.0.0.1 dans le fichier ehcach.xml en était la cause. En production, tout allait bien, localement, tout échouait et revenait à une stratégie différente, mais via le VPN, les demandes de multidiffusion étaient confrontées à un défi d'authentification et cette erreur était le résultat. Je n'avais besoin que d'une solution à court terme, alors dans ces environnements, je désactivais la configuration ehcache multicast et les choses revenaient à la normale.
C'était la ligne incriminée dans ehcache.xml
qui était simplement commentée
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446, timeToLive=32"
/>