Avoid APIs that convert a hostname to a single IP address:
java.net.Socket(String,int)
java.net.InetSocketAddress(String,int)
java.net.InetAddress.html#getByName(String)
Depending on the value of the
-Djava.net.preferIPv6Addresses=true
system property, those APIs will return an IPv4 or IPv6 address. If a client
only has IPv4 connectivity, it will fail to connect with
-Djava.net.preferIPv6Addresses=true
. If a client only has IPv6 connectivity,
it will fail to connect with -Djava.net.preferIPv6Addresses=false
.
The preferred alternative is for clients to consider all addresses returned by
java.net.InetAddress.html#getAllByName(String)
,
and try to connect to each one until a successful connection is made.
TIP: To resolve a loopback address, prefer InetAddress.getLoopbackAddress()
over hard-coding an IPv4 or IPv6 loopback address with
InetAddress.getByName("127.0.0.1")
or InetAddress.getByName("::1")
.
This is, prefer this:
Socket doConnect(String hostname, int port) throws IOException {
IOException exception = null;
for (InetAddress address : InetAddress.getAllByName(hostname)) {
try {
return new Socket(address, port);
} catch (IOException e) {
if (exception == null) {
exception = e;
} else {
exception.addSuppressed(e);
}
}
}
throw exception;
}
Socket doConnect(String hostname, int port) throws IOException {
IOException exception = null;
for (InetAddress address : InetAddress.getAllByName(hostname)) {
try {
Socket s = new Socket();
s.connect(new InetSocketAddress(address, port));
return s;
} catch (IOException e) {
if (exception == null) {
exception = e;
} else {
exception.addSuppressed(e);
}
}
}
throw exception;
}
instead of this:
Socket doConnect(String hostname, int port) throws IOException {
return new Socket(hostname, port);
}
void doConnect(String hostname, int port) throws IOException {
Socket s = new Socket();
s.connect(new InetSocketAddress(hostname, port));
}
void doConnect(String hostname, int port) throws IOException {
Socket s = new Socket();
s.connect(new InetSocketAddress(InetAddress.getByName(hostname), port));
}
Suppress false positives by adding the suppression annotation @SuppressWarnings("AddressSelection")
to the enclosing element.