Examine the internal DNS cache

Once an application has performed network access (i.e. urlconnection, parsing of xml document with external references, etc), the DNS settings get cached internally so any subsequent operation will use the previously read settings to achieve a better performance. There is one cache for successful lookups and one for unsuccessful lookups. To get the contents of 2 caches, we are using introspection because these are private elements of the InetAdress object.

import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class DNSCache {
   public static void main(String[] args) throws Exception {

      // put some values in the internal DNS cache

      // good DNS name
      InetAddress.getByName("stackoverflow.com");
      InetAddress.getByName("www.google.com");
      InetAddress.getByName("www.rgagnon.com");
      try {
         // bad DNS name
         InetAddress.getByName("bad.rgagnon.com");
      }
      catch (UnknownHostException e) {
         // do nothing
      }

      // dump the good DNS entries
      String addressCache = "addressCache";
      System.out.println("---------" + addressCache + "---------");
      printDNSCache(addressCache);

      // dump the bad DNS entries
      String negativeCache = "negativeCache";
      System.out.println("---------" + negativeCache + "---------");
      printDNSCache(negativeCache);
   }

   /**
    * By introspection, dump the InetAddress internal DNS cache
    *
    * @param cacheName  can be addressCache or negativeCache
    * @throws Exception
    */

   @SuppressWarnings({ "rawtypes", "unchecked" })
   private static void printDNSCache(String cacheName) throws Exception {
      Class<InetAddress> iaclass = InetAddress.class;
      Field acf = iaclass.getDeclaredField(cacheName);
      acf.setAccessible(true);
      Object addressCache = acf.get(null);
      Class cacheClass = addressCache.getClass();
      Field cf = cacheClass.getDeclaredField("cache");
      cf.setAccessible(true);
      Map<String, Object> cache = (Map<String, Object>) cf.get(addressCache);
      for (Map.Entry<String, Object> hi : cache.entrySet()) {
         Object cacheEntry = hi.getValue();
         Class cacheEntryClass = cacheEntry.getClass();
         Field expf = cacheEntryClass.getDeclaredField("expiration");
         expf.setAccessible(true);
         long expires = (Long) expf.get(cacheEntry);

         Field af = cacheEntryClass.getDeclaredField("addresses"); // JDK 1.7, older version maybe "address"
         af.setAccessible(true);
         InetAddress[] addresses = (InetAddress[]) af.get(cacheEntry);
         List<String> ads = new ArrayList<String>(addresses.length);

         for (InetAddress address : addresses) {
            ads.add(address.getHostAddress());
         }

         System.out.println(hi.getKey() + " "+new Date(expires) +" " +ads);
      }
   }
}

Output:

---------addressCache---------
0.0.0.0 Wed Jul 22 15:41:35 EDT 2015 [0.0.0.0]
stackoverflow.com Wed Jul 22 15:41:35 EDT 2015 [198.252.206.16]
www.google.com Wed Jul 22 15:41:35 EDT 2015 [173.194.123.49, 173.194.123.50, 173.194.123.48, 173.194.123.52, 173.194.123.51]
www.rgagnon.com Wed Jul 22 15:41:35 EDT 2015 [72.55.186.40]
---------negativeCache---------
bad.rgagnon.com Wed Jul 22 15:41:15 EDT 2015 [0.0.0.0]

To disable the caching:

public class DNSCache {
   public static void main(String[] args) throws Exception {
     java.security.Security.setProperty("networkaddress.cache.ttl" , "0"); // no cache
     java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "0"); // no cache
     ...

and the caches are empty:

---------addressCache---------
---------negativeCache---------

To cache forever:

public class DNSCache {
   public static void main(String[] args) throws Exception {
     java.security.Security.setProperty("networkaddress.cache.ttl" , "-1"); // cache forever
     java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "-1"); // cache forever
     ...

and the result is:

---------addressCache---------
0.0.0.0 Wed Dec 31 18:59:59 EST 1969 [0.0.0.0]
stackoverflow.com Wed Dec 31 18:59:59 EST 1969 [198.252.206.16]
www.google.com Wed Dec 31 18:59:59 EST 1969 [173.194.123.116, 173.194.123.114, 173.194.123.113, 173.194.123.112, 173.194.123.115]
www.rgagnon.com Wed Dec 31 18:59:59 EST 1969 [72.55.186.40]
---------negativeCache---------
bad.rgagnon.com Wed Dec 31 18:59:59 EST 1969 [0.0.0.0]

Done! Happy Coding!

Related posts:

Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java
Remove HTML tags from a file to extract only the TEXT
Java Map With Case-Insensitive Keys
Java Program to Implement an Algorithm to Find the Global min Cut in a Graph
Java Program to Check Whether an Undirected Graph Contains a Eulerian Path
Convert Character Array to String in Java
Java Program to Implement the Checksum Method for Small String Messages and Detect
A Guide to @RepeatedTest in Junit 5
How to Read HTTP Headers in Spring REST Controllers
Spring Boot - Code Structure
Java Program to Implement LinkedBlockingDeque API
Java Program to Perform Addition Operation Using Bitwise Operators
Java Program to Implement Triply Linked List
Jackson Date
Spring Boot Application as a Service
Converting a List to String in Java
Spring Security Custom AuthenticationFailureHandler
Comparing Long Values in Java
Introduction to the Java ArrayDeque
Spring Boot - Securing Web Applications
Java Program to Implement Stack using Linked List
Java Program to Search Number Using Divide and Conquer with the Aid of Fibonacci Numbers
Deploy a Spring Boot App to Azure
Introduction to Spring Method Security
Java Program to Represent Graph Using Adjacency List
Java Program to Implement a Binary Search Algorithm for a Specific Search Sequence
Primitive Type Streams in Java 8
Java Program to Find All Pairs Shortest Path
The StackOverflowError in Java
Testing in Spring Boot
Guide to Selenium with JUnit / TestNG
Send an email with an attachment