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:
Xử lý ngoại lệ trong Java (Exception Handling)
Java Program to Implement Coppersmith Freivald’s Algorithm
Guide to Guava Multimap
Java Program to Implement Min Hash
Java Program to implement Sparse Vector
Java Program to Generate All Possible Combinations of a Given List of Numbers
Introduction to Project Reactor Bus
How to Use if/else Logic in Java 8 Streams
Giới thiệu luồng vào ra (I/O) trong Java
Java Program to Implement IdentityHashMap API
Tránh lỗi ConcurrentModificationException trong Java như thế nào?
Java Program to Find the Median of two Sorted Arrays using Binary Search Approach
Java Program to Implement Expression Tree
Converting between an Array and a List in Java
Java Program to Implement Traveling Salesman Problem using Nearest neighbour Algorithm
Error Handling for REST with Spring
Adding Shutdown Hooks for JVM Applications
Java Program to Implement Heap Sort Using Library Functions
Guide to Escaping Characters in Java RegExps
Getting a File’s Mime Type in Java
Java Program to Implement ConcurrentLinkedQueue API
Java Program to Implement DelayQueue API
Java Program to Implement Dijkstra’s Algorithm using Queue
Service Registration with Eureka
Guide to the Java Clock Class
Mệnh đề Switch-case trong java
Java Program to Implement K Way Merge Algorithm
JPA/Hibernate Persistence Context
Java Program to Implement ArrayDeque API
Working with Tree Model Nodes in Jackson
Exploring the New Spring Cloud Gateway
Java – Get Random Item/Element From a List