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 Implement Meldable Heap
Java Program to Perform the Sorting Using Counting Sort
Java Program to Implement the Vigenere Cypher
The Order of Tests in JUnit
Spring Security with Maven
A Guide to the finalize Method in Java
Using the Map.Entry Java Class
Comparing Two HashMaps in Java
Introduction to Spring Data JPA
Java – Combine Multiple Collections
Java – Try with Resources
Java Program to Solve Travelling Salesman Problem for Unweighted Graph
Xử lý ngoại lệ đối với trường hợp ghi đè phương thức trong java
Java Program to Perform Optimal Paranthesization Using Dynamic Programming
Java Program to Implement Insertion Sort
Spring Cloud Series – The Gateway Pattern
Java Program to Implement Hash Tree
Spring Boot - Bootstrapping
Java Program to Implement Depth-limited Search
Từ khóa this và super trong Java
Java Program to Check whether Directed Graph is Connected using BFS
Java Program to Construct an Expression Tree for an Prefix Expression
Using Spring @ResponseStatus to Set HTTP Status Code
Weak References in Java
Java Program to Implement Direct Addressing Tables
Hướng dẫn Java Design Pattern – Command
Guide to the Java Clock Class
The Modulo Operator in Java
Java Byte Array to InputStream
Java Program to Generate All Subsets of a Given Set in the Gray Code Order
Phương thức tham chiếu trong Java 8 – Method References
Spring Boot Gradle Plugin