Okay, I’m totally hacked! java.net.URL class officially sucks! The equals method on this shining example of the JDK API mess actually does a blocking DNS lookup on the host string to resolve to an IP address and then compares the IP addresses rather than the host string. What freakin’ sense does that make?

Simple example:

URL url1 = new URL("http://foo.example.com"); URL url2 = new URL("http://example.com");

Let’s say these map to these IP addresses:

http://foo.example.com => 245.10.10.1 http://example.com => 245.10.10.1

Here’s the scary part:

url1.equals(url2) => true!

These two URLs are NOT equal, ever! They could be different web apps, have different failure IPs and even different servers using a load balancer. At 2AM they might have the same IP, at 2PM they might have different ones. They might be in different states or different countries. And here is the kicker! URL’s equals method isn’t idempotent! If you call it with an Internet connection you might get a different result than if you call it without one! Seriously! I disconnected my ethernet card and got this:

url1.equals(url2) => false!

Plus, if you have an Internet connection you have to do a DNS lookup in the equals method of URL to compare IP addresses. This is horribly slow and just a plain old bad idea. You can’t use these in Maps, Sets, Sorted anything or just ever call equals because it takes nearly a second best case to resolve the host name, even on a fast connection.

This code took over 4 minutes to execute:

Set<URL> excludeURLs = ...; // approximately 20 List<URL> testURLs = ...; // approximately 400 for (URL url : testURLs) { if (excludeURLs.contains(url)) { continue; } doSomeWork(url); }

Argh! This class sucks and I refuse to ever use it again. I’ll always use URI from now on since it doesn’t suck.

The author tag still says James Gosling, so I ask you Mr. Gosling, what were you thinking?