Freigeben über


Java and DNS Caching

I ran into some problems with a VM on Azure trying to resolve an outside URL. The problem was that even though the URL existed and was assigned, the Azure DNS server wouldn't resolve it and therefore my java code would return an Unknown Hostname exception. 

I wrote some code to debug this and quickly realized that the problem wasn't really the Azure DNS and rather something within Java. The behavior is when a name doesn't get resolved  for whatever reason the "negative" result gets cached by Java and therefore any subsequent queries for the name doesn't get queried. So I wrote a little Java code to explore this more. 

The key thing is, prior to making the call for the nameserver we must first  set the cache TTL value. There are two of these; 1. for the positive or successful queries and 2. for the negative or the failed queries. The values for each can be found at here. 

networkaddress.cache.ttl (default: -1)
Indicates the caching policy for successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the successful lookup. A value of -1 indicates "cache forever".

networkaddress.cache.negative.ttl (default: 10)
Indicates the caching policy for un-successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the failure for un-successful lookups. A value of 0 indicates "never cache". A value of -1 indicates "cache forever".

        java.security.Security.setProperty("networkaddress.cache.ttl", successfulCacheValue);

        java.security.Security.setProperty("networkaddress.cache.negative.ttl", failedCachedValue);

Just in case you want to confirm the set value you can read it like this: 

    

System.out.println(

        "Positive cache: " + java.security.Security.getProperty("networkaddress.cache.ttl") + "\n" +

        "Negative cache: " + java.security.Security.getProperty("networkaddress.cache.negative.ttl")

);

Next attempt resolve the name. In my case the url was passed-in as a command line argument.

try {

        InetAddress inetAddress = InetAddress.getByName(args[1]);

        displayData(args[1], inetAddress);

} catch (UnknownHostException e) {

        System.out.println("Unknown hostname");

        e.printStackTrace();

}

 

public static void displayData(String hostName, InetAddress inetAddress) {

        System.out.println("Hostname: " + hostName);

        System.out.println("Canonical Host Name:" + inetAddress.getCanonicalHostName());

        System.out.println("Host Name:" + inetAddress.getHostName());

        System.out.println("Host Address:" + inetAddress.getHostAddress());

}

 

And that's it. Happy coding..