Getting java.net.SocketException
when trying to start a multicast provider:
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)
This was caused by an IPv6 address being returned from java.net.NetworkInterface.getDefault()
. I'm on a Macbook and was using wireless -- p2p0 (used for AirDrop) was returned as the default network interface but my p2p0 only has an IPv6 ether
entry (found by running ipconfig
).
Two solutions, both of which worked for me (I prefer the first because it works whether you are using a wired or wireless connection)
- Start the JVM with
-Djava.net.preferIPv4Stack=true
. This caused java.net.NetworkInterface.getDefault()
to return my vboxnet0 network interface -- not sure what you'll get if you're not running a host-only VM.
- Turn off wireless and use a wired connection
A slight variation on the accepted answer: You can also add the following line of code to your java code:
System.setProperty("java.net.preferIPv4Stack", "true");
You need to add certain configurations to Java VM before you can join a Multicast socket in any machine.
First add this line before attempting any connection to make sure you will get only IPv4 addresses:
System.setProperty("java.net.preferIPv4Stack", "true");
In most of the cases your computer has more than one network interface, so you need to choose the correct one:
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 my case I had just began using a VPN to a network that required authentication. My app would start and could connect to its databases through the pipe fine but my configuration for distributed cache using the IP 230.0.0.1 in ehcach.xml was the cause. In production all was well, locally it would simply fail and rollback to a different strategy but via the VPN the multicast requests were met with an authentication challenge and this error was the result. I only required a short term fix so in these environments I disable the ehcache multicast configuration and things returned to normal.
This was the offending line in ehcache.xml
which was simply commented out
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446, timeToLive=32"
/>