So you have an application. It was written (as far as you know) without IPv6 in mind, and now it has to work with IPv6. How hard is that going to be? Well, it depends on the application. Most of the following is not really Java specific (but some of it is).
Start with a simple grep
for “IPv4”, “IPv6”, “Inet4Address”, “Inet6Address”. The locations will be those where someone has been specific about the IP protocol. It may be valid, it may be an area where someone was thinking ahead or flagging an issue, or it may be an area needing adjustment. Also look for InetAddress, just in case someone is using the superclass, but using it with an IPv4 bias. And obviously look for IP address literals of any kind,
The migration mantra is “send, get, input, display, store, retrieve, use”.
If your application sends an IP address anywhere, then those areas of code may need to be adjusted. If the code is using the InetAddress
class, the changes may be minimal. If you are lucky.
If your application gets IP addresses from anywhere (over the wire, from other devices, via DNS etc), then those areas of code may need to be adjusted. If the code is using the InetAddress
class, the changes may be minimal. If you are lucky. Look for uses of InetAddress
methods like getByName()
, getAllByName()
, getByAddress()
, getAddress()
, getHostAddress()
, getHostName()
, getCanonicalHostName()
and so on.
Watch out for code using getByName()
with DNS names; such code probably should be using getAllByName()
and dealing with multiple addresses.
If your application displays an IP address, you will almost certainly need to adjust the code, as Java’s own display possibilities for IP addresses are very limited, and more so for IPv6 addresses (no compression). Also, IPv6 addresses need more space to display on screen or to print out, so forms and what-have-you will need adjusting.
If the user must input IP addresses you have the display issue as well, plus the need to validate the input. Simple validation by attempting to convert the input from a string to an InetAddress
(getByName()
) is probably not good enough, and certainly not if you need any kind of dynamic validity checking.
If your application stores addresses anywhere, then those areas of code – and the storage schema – will need to be checked and probably adjusted. IPv6 addresses take up more room in storage, and any back-end data validation that is going on needs to take IPv6 into account. If you are using the InetAddress
class you may be lucky.
If your application retrieves IP addresses from a database – well, I’m sure by now you get the idea.
And the biggy – if your application uses IP addresses itself, all the related logic will need to be checked and possibly adjusted. Listening on ports and connecting to ports is relatively straightforward provided you use the InetAddress
class, but even then you have to do (almost) everything twice.
In all of the above areas, look for places where assumptions have been made about the size of an address – display size, storage size, etc. These are distressingly commonly decoupled from the objects that will use the space. And also search your codebase for any hardcoded addresses.
Don’t forget configuration and logging modules; there’s no point having an IPv6-aware application with no way to configure it to actually use IPv6. And with logging, don’t forget any external consumers of the log data – monitoring programs and the like. These will need to be modified to handle the different output from your application.
Don’t forget your test rig; from an IPv6 conversion perspective, your test rig is an “application” and all of the above applies equally well there. And any test that involves IP addresses implicitly or explicitly must be extended or additional tests added to make sure that the tests test the IPv6 cases as well.
When adjusting, be aware of IPv4 bias in variable names, function names, class names and so on. Fix it where you can, document it where you can’t.
Finally, be aware that some Java implementations do not properly prefer IPv6 addresses over IPv4 addresses. Some have a system configuration setting for this, some have the setting and ignore it. Do getByName()
on a known dual-stack name and see if you get an IPv4 address or an IPv6 address.
The above is just the beginning; this is a surprisingly deep rabbit hole. With Java, by far the majority of IPv6 issues are not really language issues, they are more issues of application design and coding practice.
That’s not really good news, though, is it?
[This article was copied from my personal blog, where it was originally posted on September 15, 2012]