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:
Immutable ArrayList in Java
Inheritance with Jackson
Date Time trong Java 8
Java Program to Implement Double Order Traversal of a Binary Tree
Create Java Applet to Simulate Any Sorting Technique
Guide to ThreadLocalRandom in Java
Java Program to Implement AttributeList API
Java InputStream to Byte Array and ByteBuffer
New Features in Java 9
Java Program to Perform Preorder Recursive Traversal of a Given Binary Tree
Spring MVC Setup with Kotlin
Spring Boot - Interceptor
Java Program to Implement LinkedList API
Spring Boot Annotations
Java Program to Implement RoleList API
Receive email using IMAP
Hướng dẫn Java Design Pattern – Intercepting Filter
Java Program to Generate Random Partition out of a Given Set of Numbers or Characters
Exploring the New Spring Cloud Gateway
Guide to the Fork/Join Framework in Java
Java Convenience Factory Methods for Collections
Spring Cloud AWS – S3
Java Copy Constructor
Guide to the Java TransferQueue
Java Program to Implement Graham Scan Algorithm to Find the Convex Hull
Custom JUnit 4 Test Runners
Spring REST API + OAuth2 + Angular (using the Spring Security OAuth legacy stack)
Java Program to Find the Minimum value of Binary Search Tree
Java Program to Check Whether it is Weakly Connected or Strongly Connected for a Directed Graph
Spring Boot - Exception Handling
Guide to the Java ArrayList
Introduction to Spring Data REST