Skip to content

Commit 124d667

Browse files
committed
add support for jdk 6 #1
1 parent 243d64b commit 124d667

File tree

2 files changed

+54
-15
lines changed

2 files changed

+54
-15
lines changed

.travis.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
language: java
22
jdk:
3-
# java.lang.NoSuchMethodException: java.net.InetAddress$CacheEntry.<init>([Ljava.net.InetAddress;, long)
4-
# at com.alibaba.dcm.internal.InetAddressCacheUtil.createCacheEntry
5-
# - openjdk6
3+
- openjdk6
64
- oraclejdk7
75
- openjdk7
86
- oraclejdk8

src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtil.java

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* @author Jerry Lee (oldratlee at gmail dot com)
2929
* @see InetAddress
3030
* @see InetAddress#addressCache
31+
* @see InetAddress.CacheEntry
3132
* @see InetAddress#cacheInitIfNeeded()
3233
* @see InetAddress#cacheAddresses(String, InetAddress[], boolean)
3334
*/
@@ -61,7 +62,17 @@ static Object createCacheEntry(String host, String[] ips, long expiration)
6162
IllegalAccessException, InvocationTargetException, InstantiationException {
6263
String className = "java.net.InetAddress$CacheEntry";
6364
Class<?> clazz = Class.forName(className);
64-
Constructor<?> constructor = clazz.getDeclaredConstructor(InetAddress[].class, long.class);
65+
66+
// InetAddress.CacheEntry has only a constructor:
67+
// - for jdk 6, constructor signature is CacheEntry(Object address, long expiration)
68+
// - for jdk 7+, constructor signature is CacheEntry(InetAddress[] addresses, long expiration)
69+
// code in jdk 6:
70+
// http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/net/InetAddress.java#InetAddress.CacheEntry
71+
// code in jdk 7:
72+
// http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/net/InetAddress.java#InetAddress.CacheEntry
73+
// code in jdk 8:
74+
// http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/net/InetAddress.java#InetAddress.CacheEntry
75+
Constructor<?> constructor = clazz.getDeclaredConstructors()[0];
6576
constructor.setAccessible(true);
6677
return constructor.newInstance(toInetAddressArray(host, ips), expiration);
6778
}
@@ -90,9 +101,11 @@ static Object getAddressCacheFieldOfInetAddress()
90101
throws NoSuchFieldException, IllegalAccessException {
91102
if (ADDRESS_CACHE == null) {
92103
synchronized (InetAddressCacheUtil.class) {
93-
final Field cacheField = InetAddress.class.getDeclaredField("addressCache");
94-
cacheField.setAccessible(true);
95-
ADDRESS_CACHE = cacheField.get(InetAddress.class);
104+
if (ADDRESS_CACHE == null) { // double check
105+
final Field cacheField = InetAddress.class.getDeclaredField("addressCache");
106+
cacheField.setAccessible(true);
107+
ADDRESS_CACHE = cacheField.get(InetAddress.class);
108+
}
96109
}
97110
}
98111
return ADDRESS_CACHE;
@@ -150,17 +163,45 @@ public static List<DnsCacheEntry> listInetAddressCache()
150163
return list;
151164
}
152165

166+
167+
static volatile Field expirationFieldOfInetAddress$CacheEntry = null;
168+
static volatile Field addressesFieldOfInetAddress$CacheEntry = null;
169+
153170
static DnsCacheEntry inetAddress$CacheEntry2DnsCacheEntry(String host, Object entry)
154171
throws NoSuchFieldException, IllegalAccessException {
155-
Class<?> cacheEntryClass = entry.getClass();
156-
157-
Field expirationField = cacheEntryClass.getDeclaredField("expiration");
158-
expirationField.setAccessible(true);
159-
long expiration = (Long) expirationField.get(entry);
172+
if (expirationFieldOfInetAddress$CacheEntry == null || addressesFieldOfInetAddress$CacheEntry == null) {
173+
synchronized (InetAddressCacheUtil.class) {
174+
if (expirationFieldOfInetAddress$CacheEntry == null) { // double check
175+
Class<?> cacheEntryClass = entry.getClass();
176+
// InetAddress.CacheEntry has 2 filed:
177+
// - for jdk 6, address and expiration
178+
// - for jdk 7+, addresses(*renamed* from 6!) and expiration
179+
// code in jdk 6:
180+
// http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/net/InetAddress.java#InetAddress.CacheEntry
181+
// code in jdk 7:
182+
// http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/net/InetAddress.java#InetAddress.CacheEntry
183+
// code in jdk 8:
184+
// http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/net/InetAddress.java#InetAddress.CacheEntry
185+
final Field[] fields = cacheEntryClass.getDeclaredFields();
186+
for (Field field : fields) {
187+
final String name = field.getName();
188+
if (name.equals("expiration")) {
189+
field.setAccessible(true);
190+
expirationFieldOfInetAddress$CacheEntry = field;
191+
} else if (name.startsWith("address")) { // use startWith so works for jdk 6 and jdk 7+
192+
field.setAccessible(true);
193+
addressesFieldOfInetAddress$CacheEntry = field;
194+
} else {
195+
throw new IllegalStateException("JDK add new Field " + name +
196+
" for class InetAddress.CacheEntry, report bug for dns-cache-manipulator lib!");
197+
}
198+
}
199+
}
200+
}
201+
}
160202

161-
Field addressesField = cacheEntryClass.getDeclaredField("addresses");
162-
addressesField.setAccessible(true);
163-
InetAddress[] addresses = (InetAddress[]) addressesField.get(entry);
203+
long expiration = (Long) expirationFieldOfInetAddress$CacheEntry.get(entry);
204+
InetAddress[] addresses = (InetAddress[]) addressesFieldOfInetAddress$CacheEntry.get(entry);
164205

165206
String[] ips = new String[addresses.length];
166207
for (int i = 0; i < addresses.length; i++) {

0 commit comments

Comments
 (0)