@@ -221,7 +221,7 @@ public static DnsCache listInetAddressCache()
221221 return new DnsCache (convert (cache ), convert (negativeCache ));
222222 }
223223
224- private static List <DnsCacheEntry > convert (Map <String , Object > cache ) throws IllegalAccessException {
224+ private static List <DnsCacheEntry > convert (Map <String , Object > cache ) throws IllegalAccessException , ClassNotFoundException {
225225 final List <DnsCacheEntry > ret = new ArrayList <DnsCacheEntry >();
226226 for (Map .Entry <String , Object > entry : cache .entrySet ()) {
227227 final String host = entry .getKey ();
@@ -234,41 +234,8 @@ private static List<DnsCacheEntry> convert(Map<String, Object> cache) throws Ill
234234 return ret ;
235235 }
236236
237-
238- private static volatile Field expirationFieldOfInetAddress$CacheEntry = null ;
239- private static volatile Field addressesFieldOfInetAddress$CacheEntry = null ;
240-
241- private static DnsCacheEntry inetAddress$CacheEntry2DnsCacheEntry (String host , Object entry ) throws IllegalAccessException {
242- if (expirationFieldOfInetAddress$CacheEntry == null || addressesFieldOfInetAddress$CacheEntry == null ) {
243- synchronized (InetAddressCacheUtilForJava8Minus .class ) {
244- if (expirationFieldOfInetAddress$CacheEntry == null || addressesFieldOfInetAddress$CacheEntry == null ) { // double check
245- Class <?> cacheEntryClass = entry .getClass ();
246- // InetAddress.CacheEntry has 2 filed:
247- // - for jdk 6, address and expiration
248- // - for jdk 7+, addresses(*renamed*!) and expiration
249- // code in jdk 6:
250- // https://hg.openjdk.java.net/jdk6/jdk6/jdk/file/8deef18bb749/src/share/classes/java/net/InetAddress.java#l739
251- // code in jdk 7:
252- // https://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/4dd5e486620d/src/share/classes/java/net/InetAddress.java#l742
253- // code in jdk 8:
254- // https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/45e4e636b757/src/share/classes/java/net/InetAddress.java#l748
255- final Field [] fields = cacheEntryClass .getDeclaredFields ();
256- for (Field field : fields ) {
257- final String name = field .getName ();
258- if (name .equals ("expiration" )) {
259- field .setAccessible (true );
260- expirationFieldOfInetAddress$CacheEntry = field ;
261- } else if (name .startsWith ("address" )) { // use startWith so works for jdk 6 and jdk 7+
262- field .setAccessible (true );
263- addressesFieldOfInetAddress$CacheEntry = field ;
264- } else {
265- throw new IllegalStateException ("JDK add new Field " + name +
266- " for class InetAddress.CacheEntry, report issue for dns-cache-manipulator lib!" );
267- }
268- }
269- }
270- }
271- }
237+ private static DnsCacheEntry inetAddress$CacheEntry2DnsCacheEntry (String host , Object entry ) throws IllegalAccessException , ClassNotFoundException {
238+ initFieldsOfInetAddress$CacheEntry ();
272239
273240 final long expiration = expirationFieldOfInetAddress$CacheEntry .getLong (entry );
274241
@@ -278,6 +245,49 @@ private static List<DnsCacheEntry> convert(Map<String, Object> cache) throws Ill
278245 return new DnsCacheEntry (host , ips , expiration );
279246 }
280247
248+ /**
249+ * {@link InetAddress.CacheEntry.expiration}
250+ */
251+ private static volatile Field expirationFieldOfInetAddress$CacheEntry = null ;
252+ /**
253+ * {@link InetAddress.CacheEntry.expiration}
254+ */
255+ private static volatile Field addressesFieldOfInetAddress$CacheEntry = null ;
256+
257+ private static void initFieldsOfInetAddress$CacheEntry () throws ClassNotFoundException {
258+ if (expirationFieldOfInetAddress$CacheEntry != null && addressesFieldOfInetAddress$CacheEntry != null ) return ;
259+
260+ final Class <?> cacheEntryClass = Class .forName ("java.net.InetAddress$CacheEntry" );
261+ synchronized (InetAddressCacheUtilForJava8Minus .class ) {
262+ // double check
263+ if (expirationFieldOfInetAddress$CacheEntry != null && addressesFieldOfInetAddress$CacheEntry != null ) return ;
264+
265+ // InetAddress.CacheEntry has 2 filed:
266+ // - for jdk 6, address and expiration
267+ // - for jdk 7+, addresses(*renamed*!) and expiration
268+ // code in jdk 6:
269+ // https://hg.openjdk.java.net/jdk6/jdk6/jdk/file/8deef18bb749/src/share/classes/java/net/InetAddress.java#l739
270+ // code in jdk 7:
271+ // https://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/4dd5e486620d/src/share/classes/java/net/InetAddress.java#l742
272+ // code in jdk 8:
273+ // https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/45e4e636b757/src/share/classes/java/net/InetAddress.java#l748
274+ final Field [] fields = cacheEntryClass .getDeclaredFields ();
275+ for (Field field : fields ) {
276+ final String name = field .getName ();
277+ if (name .equals ("expiration" )) {
278+ field .setAccessible (true );
279+ expirationFieldOfInetAddress$CacheEntry = field ;
280+ } else if (name .startsWith ("address" )) { // use startWith so works for jdk 6 and jdk 7+
281+ field .setAccessible (true );
282+ addressesFieldOfInetAddress$CacheEntry = field ;
283+ } else {
284+ throw new IllegalStateException ("JDK add new Field " + name +
285+ " for class InetAddress.CacheEntry, report issue for dns-cache-manipulator lib!" );
286+ }
287+ }
288+ }
289+ }
290+
281291 public static void clearInetAddressCache () throws NoSuchFieldException , IllegalAccessException , ClassNotFoundException {
282292 synchronized (getAddressCacheOfInetAddress ()) {
283293 getCache ().clear ();
0 commit comments