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:
Properties with Spring and Spring Boot
SOAP Web service: Authentication trong JAX-WS
Java Program to Implement Circular Singly Linked List
Spring Security and OpenID Connect
Mảng (Array) trong Java
Hướng dẫn kết nối cơ sở dữ liệu với Java JDBC
How to Store Duplicate Keys in a Map in Java?
Lớp TreeMap trong Java
Sort a HashMap in Java
Assertions in JUnit 4 and JUnit 5
Java Program to Implement Wagner and Fisher Algorithm for online String Matching
Java Program to Optimize Wire Length in Electrical Circuit
Java Program to Generate a Random Subset by Coin Flipping
Java Program to Find the Peak Element of an Array O(n) time (Naive Method)
Working with Network Interfaces in Java
Chuyển đổi giữa các kiểu dữ liệu trong Java
Spring Boot - Service Components
Primitive Type Streams in Java 8
A Custom Media Type for a Spring REST API
Hướng dẫn Java Design Pattern – Decorator
Spring 5 Testing with @EnabledIf Annotation
@DynamicUpdate with Spring Data JPA
Java Program to Implement Heap
Spring Boot - Enabling HTTPS
Java Program to Implement Johnson’s Algorithm
Guide to Apache Commons CircularFifoQueue
Abstract class và Interface trong Java
Java 8 – Powerful Comparison with Lambdas
Java Program to Perform Complex Number Multiplication
Spring Boot - Build Systems
A Guide to Java SynchronousQueue
Java Program to Perform Preorder Non-Recursive Traversal of a Given Binary Tree