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:
DynamoDB in a Spring Boot Application Using Spring Data
Java – Reader to String
Guide to java.util.concurrent.Future
How to Set TLS Version in Apache HttpClient
Spring Boot - Zuul Proxy Server and Routing
Netflix Archaius with Various Database Configurations
Java Program to Implement Rope
Java – Reader to Byte Array
Java Program to Implement Gale Shapley Algorithm
Java Web Services – JAX-WS – SOAP
Spring @RequestParam Annotation
HashSet trong java
Serialize Only Fields that meet a Custom Criteria with Jackson
Java Program to Implement ArrayBlockingQueue API
Java Program to Perform Deletion in a BST
So sánh HashSet, LinkedHashSet và TreeSet trong Java
Java Program to Implement Knapsack Algorithm
Java Program to Implement HashSet API
Java Program to find the number of occurrences of a given number using Binary Search approach
Configure a Spring Boot Web Application
Java Program to Implement Dijkstra’s Algorithm using Priority Queue
Java Program to Find Path Between Two Nodes in a Graph
Java – Write an InputStream to a File
Java Program to Implement the Program Used in grep/egrep/fgrep
Ép kiểu trong Java (Type casting)
Implementing a Binary Tree in Java
Java Program to Implement LinkedBlockingDeque API
Java Program to Implement Slicker Algorithm that avoids Triangulation to Find Area of a Polygon
Entity To DTO Conversion for a Spring REST API
Java Program to Implement Double Ended Queue
Java Program to Optimize Wire Length in Electrical Circuit
Ignore Null Fields with Jackson