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:
Java Program to Perform Encoding of a Message Using Matrix Multiplication
Java Program to Check whether Undirected Graph is Connected using BFS
Giới thiệu luồng vào ra (I/O) trong Java
Guide to java.util.concurrent.Future
Exploring the Spring Boot TestRestTemplate
Chuyển đổi giữa các kiểu dữ liệu trong Java
The Dining Philosophers Problem in Java
How to Get the Last Element of a Stream in Java?
Java Program to Implement Sieve Of Sundaram
Java Program to Implement Knapsack Algorithm
Java Program to Find the Longest Path in a DAG
Servlet 3 Async Support with Spring MVC and Spring Security
Exploring the New Spring Cloud Gateway
Use Liquibase to Safely Evolve Your Database Schema
Spring Boot - Tracing Micro Service Logs
Validations for Enum Types
Lớp Collections trong Java (Collections Utility Class)
Java Program to Implement Hash Tree
Configuring a DataSource Programmatically in Spring Boot
Create a Custom Auto-Configuration with Spring Boot
Spring Boot - Application Properties
Notify User of Login From New Device or Location
Java Program to Check if any Graph is Possible to be Constructed for a Given Degree Sequence
Introduction to Spring Security Expressions
Java Program to Implement Heap
Java Program to Generate a Random UnDirected Graph for a Given Number of Edges
Java Program to Implement SimpeBindings API
Introduction to Java 8 Streams
Shuffling Collections In Java
Guide to Selenium with JUnit / TestNG
Map Interface trong java
Java Program to Implement AttributeList API