IPv6 usage is slowly starting nowadays, so I'm currently in the process of fixing and updating all applications to be prepared for IPv6.
One of the applications is the Java editor JOSM (http://josm.openstreetmap.de/). Java does not really use IPv6 in the default configuration even if the OS uses IPv6.
According to
http://docs.oracle.com/javase/1.5.0/docs/guide/net/ipv6_guide/#using
I set java.net.preferIPv6Addresses
to true
to let it use IPv6. Result have been user bug reports about broken internet connection.
It seems Java only switches to use IPv6 address instead of IPv4, but does nothing else. All C/C++ based software I maintain has been changed to check and try all available IP addresses, so broken IPv6 (or IPv4) addresses are skipped as long as one of the addresses works. For me it looks like Java only tries once, which does not work in real world.
Also usually the OS prefers IPv4 over IPv6, when IPv6 is tunneled. It seems like Java does ignore this settings as well.
So my question is: Are there any good ways to get a Java application to use IPV6 by default when available without breaking the application for IPv4 users.
User-bug reports: http://josm.openstreetmap.de/ticket/8562, http://josm.openstreetmap.de/ticket/8627.
It seems that topic is interesting for others as well, so I describe my current solution.
This solution seems to work, we have about 4% IPv6 connections in our logs ATM, but is is not really a satisfying solution.
/**
* Check if IPv6 can be safely enabled and do so. Because this cannot be done after network activation,
* disabling or enabling IPV6 may only be done with next start.
*/
private static void checkIPv6() {
if ("auto".equals(Main.pref.get("prefer.ipv6", "auto"))) {
new Thread(new Runnable() { /* this may take some time (DNS, Connect) */
public void run() {
boolean hasv6 = false;
boolean wasv6 = Main.pref.getBoolean("validated.ipv6", false);
try {
/* Use the check result from last run of the software, as after the test, value
changes have no effect anymore */
if (wasv6) {
Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
}
for (InetAddress a : InetAddress.getAllByName("josm.openstreetmap.de")) {
if (a instanceof Inet6Address) {
if (a.isReachable(1000)) {
/* be sure it REALLY works */
Socket s = new Socket();
s.connect(new InetSocketAddress(a, 80), 1000);
s.close();
Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
if (!wasv6) {
Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
} else {
Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
}
hasv6 = true;
}
break; /* we're done */
}
}
} catch (IOException | SecurityException e) {
if (Main.isDebugEnabled()) {
Main.debug("Exception while checking IPv6 connectivity: "+e);
}
}
if (wasv6 && !hasv6) {
Main.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
Main.pref.put("validated.ipv6", hasv6); // be sure it is stored before the restart!
new RestartAction().actionPerformed(null);
}
Main.pref.put("validated.ipv6", hasv6);
}
}, "IPv6-checker").start();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With