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:
The Spring @Controller and @RestController Annotations
Java Program to Implement Slicker Algorithm that avoids Triangulation to Find Area of a Polygon
Java Program to Check if a Matrix is Invertible
Java Program to Implement Nth Root Algorithm
Hướng dẫn Java Design Pattern – Builder
Java Program to Implement Uniform-Cost Search
Serverless Functions with Spring Cloud Function
New Features in Java 14
Java Program to find the peak element of an array using Binary Search approach
Spring Boot - OAuth2 with JWT
Spring REST API + OAuth2 + Angular
Java Program to implement Bit Matrix
Guide to Spring 5 WebFlux
Converting String to Stream of chars
Spring Boot - Cloud Configuration Server
An Example of Load Balancing with Zuul and Eureka
Java Program to Implement Dijkstra’s Algorithm using Queue
Merging Streams in Java
Java Program to Check Whether a Weak Link i.e. Articulation Vertex Exists in a Graph
Spring RequestMapping
Java Program to Generate All Pairs of Subsets Whose Union Make the Set
Converting Between a List and a Set in Java
Connect through a Proxy
String Processing with Apache Commons Lang 3
Flattening Nested Collections in Java
Java Program to Implement Hash Tables Chaining with Binary Trees
Spring WebClient Requests with Parameters
Java Program to Implement Circular Doubly Linked List
Guide to the Volatile Keyword in Java
Spring Boot - Interceptor
Java Program to Implement Sorted Circularly Singly Linked List
Generating Random Numbers in a Range in Java