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:
Hướng dẫn Java Design Pattern – Prototype
Java Program to Test Using DFS Whether a Directed Graph is Weakly Connected or Not
Java Program to Implement the String Search Algorithm for Short Text Sizes
Java 8 Streams peek() API
Java Program to Implement Sieve Of Eratosthenes
Các kiểu dữ liệu trong java
Java Program to Perform Postorder Recursive Traversal of a Given Binary Tree
HttpClient Connection Management
Java Program to Check if a Given Binary Tree is an AVL Tree or Not
Java Program to Implement Borwein Algorithm
Java Program to Implement Hash Tables Chaining with List Heads
Java Program to Check Cycle in a Graph using Graph traversal
Java Program to Implement Quick sort
Introduction to Spring Data JDBC
Join and Split Arrays and Collections in Java
Java 8 Predicate Chain
Giới thiệu thư viện Apache Commons Chain
JUnit5 @RunWith
Java Program to Check if a Matrix is Invertible
Java Program to Implement LinkedBlockingDeque API
Java Program to Implement Sorted Array
File Upload with Spring MVC
Validate email address exists or not by Java Code
Number Formatting in Java
Java Program to Implement Binary Heap
Java Program to Print only Odd Numbered Levels of a Tree
“Stream has already been operated upon or closed” Exception in Java
Java Program to Implement PrinterStateReasons API
Java Program to Print the Kind of Rotation the AVL Tree is Undergoing
Debug a JavaMail Program
A Quick Guide to Using Keycloak with Spring Boot
The Dining Philosophers Problem in Java