7012768: InetAddress lookupTable leaks/deadlocks when using unsupported name service spi
authorchegar
Fri, 21 Jan 2011 17:02:57 +0000
changeset 7995 8168047d48c2
parent 7993 8778b8786a81
child 7996 bea538812ec8
7012768: InetAddress lookupTable leaks/deadlocks when using unsupported name service spi Reviewed-by: alanb, michaelm
jdk/src/share/classes/java/net/InetAddress.java
jdk/test/java/net/InetAddress/B4762344.java
jdk/test/java/net/InetAddress/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
jdk/test/java/net/InetAddress/Simple1NameServiceDescriptor.java
jdk/test/java/net/InetAddress/Simple2NameServiceDescriptor.java
jdk/test/java/net/InetAddress/SimpleNameService.java
jdk/test/sun/net/InetAddress/nameservice/B6442088.java
jdk/test/sun/net/InetAddress/nameservice/CacheTest.java
jdk/test/sun/net/InetAddress/nameservice/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
jdk/test/sun/net/InetAddress/nameservice/SimpleNameService.java
jdk/test/sun/net/InetAddress/nameservice/SimpleNameServiceDescriptor.java
jdk/test/sun/net/InetAddress/nameservice/chaining/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
jdk/test/sun/net/InetAddress/nameservice/chaining/Providers.java
jdk/test/sun/net/InetAddress/nameservice/chaining/Simple1NameServiceDescriptor.java
jdk/test/sun/net/InetAddress/nameservice/chaining/Simple2NameServiceDescriptor.java
jdk/test/sun/net/InetAddress/nameservice/chaining/SimpleNameService.java
jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java
jdk/test/sun/net/InetAddress/nameservice/deadlock/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameService.java
jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameServiceDescriptor.java
jdk/test/sun/net/InetAddress/nameservice/simple/CacheTest.java
jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCaching.java
jdk/test/sun/net/InetAddress/nameservice/simple/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameService.java
jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameServiceDescriptor.java
--- a/jdk/src/share/classes/java/net/InetAddress.java	Thu Jan 20 15:23:57 2011 +0000
+++ b/jdk/src/share/classes/java/net/InetAddress.java	Fri Jan 21 17:02:57 2011 +0000
@@ -677,8 +677,7 @@
 
     static InetAddressImpl  impl;
 
-    private static HashMap<String, InetAddress[]> lookupTable
-        = new HashMap<String, InetAddress[]>();
+    private static final HashMap<String, Void> lookupTable = new HashMap<>();
 
     /**
      * Represents a cache entry
@@ -737,7 +736,7 @@
 
                 // As we iterate in insertion order we can
                 // terminate when a non-expired entry is found.
-                LinkedList<String> expired = new LinkedList<String>();
+                LinkedList<String> expired = new LinkedList<>();
                 long now = System.currentTimeMillis();
                 for (String key : cache.keySet()) {
                     CacheEntry entry = cache.get(key);
@@ -1227,43 +1226,45 @@
         //         lookupTable and return null so the
         //         following code would do  a lookup itself.
         if ((addresses = checkLookupTable(host)) == null) {
-            // This is the first thread which looks up the addresses
-            // this host or the cache entry for this host has been
-            // expired so this thread should do the lookup.
-            for (NameService nameService : nameServices) {
-                try {
-                    /*
-                     * Do not put the call to lookup() inside the
-                     * constructor.  if you do you will still be
-                     * allocating space when the lookup fails.
-                     */
+            try {
+                // This is the first thread which looks up the addresses
+                // this host or the cache entry for this host has been
+                // expired so this thread should do the lookup.
+                for (NameService nameService : nameServices) {
+                    try {
+                        /*
+                         * Do not put the call to lookup() inside the
+                         * constructor.  if you do you will still be
+                         * allocating space when the lookup fails.
+                         */
 
-                    addresses = nameService.lookupAllHostAddr(host);
-                    success = true;
-                    break;
-                } catch (UnknownHostException uhe) {
-                    if (host.equalsIgnoreCase("localhost")) {
-                        InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
-                        addresses = local;
+                        addresses = nameService.lookupAllHostAddr(host);
                         success = true;
                         break;
-                    }
-                    else {
-                        addresses = unknown_array;
-                        success = false;
-                        ex = uhe;
+                    } catch (UnknownHostException uhe) {
+                        if (host.equalsIgnoreCase("localhost")) {
+                            InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
+                            addresses = local;
+                            success = true;
+                            break;
+                        }
+                        else {
+                            addresses = unknown_array;
+                            success = false;
+                            ex = uhe;
+                        }
                     }
                 }
+
+                // Cache the addresses.
+                cacheAddresses(host, addresses, success);
+                if (!success && ex != null)
+                    throw ex;
+            } finally {
+                // Delete host from the lookupTable and notify
+                // all threads waiting on the lookupTable monitor.
+                updateLookupTable(host);
             }
-
-            // Cache the addresses.
-            cacheAddresses(host, addresses, success);
-            // Delete the host from the lookupTable, and
-            // notify all threads waiting for the monitor
-            // for lookupTable.
-            updateLookupTable(host);
-            if (!success && ex != null)
-                throw ex;
         }
 
         return addresses;
@@ -1271,16 +1272,13 @@
 
 
     private static InetAddress[] checkLookupTable(String host) {
-        // make sure addresses is null.
-        InetAddress[] addresses = null;
-
         synchronized (lookupTable) {
             // If the host isn't in the lookupTable, add it in the
             // lookuptable and return null. The caller should do
             // the lookup.
             if (lookupTable.containsKey(host) == false) {
                 lookupTable.put(host, null);
-                return addresses;
+                return null;
             }
 
             // If the host is in the lookupTable, it means that another
@@ -1298,10 +1296,11 @@
         // the host. This thread should retry to get the addresses
         // from the addressCache. If it doesn't get the addresses from
         // the cache, it will try to look up the addresses itself.
-        addresses = getCachedAddresses(host);
+        InetAddress[] addresses = getCachedAddresses(host);
         if (addresses == null) {
             synchronized (lookupTable) {
                 lookupTable.put(host, null);
+                return null;
             }
         }
 
--- a/jdk/test/java/net/InetAddress/B4762344.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 4762344
- * @summary 2nd nameservice provider is non functional
- * @build B4762344 SimpleNameService Simple1NameServiceDescriptor Simple2NameServiceDescriptor
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=simple1,sun -Dsun.net.spi.nameservice.provider.2=simple2,sun B4762344
- */
-
-import java.net.*;
-import java.util.*;
-
-
-public class B4762344 {
-    private static String[][] hostnames = new String[][] {
-            // both providers know this host, but with different address
-            new String[] {"blade", "10.0.0.1"},
-            // provider1 knwos this host
-            new String[] {"blade.domain1", "10.0.0.2"},
-            // provider2 knows this host
-            new String[] {"blade.domain2", "20.0.0.2"}
-        };
-    private static String[][] hostaddrs = new String[][] {
-            new String[] {"10.0.0.1", "blade"},
-            new String[] {"10.0.0.2", "blade.domain1"},
-            new String[] {"20.0.0.2", "blade.domain2"}
-        };
-
-    public static void main(String[] args) throws Exception {
-        for (int i = 0; i < hostnames.length; i++) {
-            doLookup(hostnames[i][0], hostnames[i][1]);
-        }
-        for (int i = 0; i < hostaddrs.length; i++) {
-            doReverseLookup(hostaddrs[i][0], hostaddrs[i][1]);
-        }
-    }
-
-    private static void doLookup(String host, String addr) throws Exception {
-        String res = InetAddress.getByName(host).getHostAddress();
-        if (!res.equals(addr)) {
-            throw new RuntimeException("Test failed: wrong address for host " + host);
-        }
-    }
-
-    private static void doReverseLookup(String addr, String host) throws Exception {
-        StringTokenizer tokenizer = new StringTokenizer(addr, ".");
-        byte addrs[] = new byte[4];
-        for (int i = 0; i < 4; i++) {
-            addrs[i] = (byte)Integer.parseInt(tokenizer.nextToken());
-        }
-        String res = InetAddress.getByAddress(addrs).getHostName();
-        if (!res.equals(host)) {
-            throw new RuntimeException("Test failed: wrong host name for address " + addr);
-        }
-    }
-}
--- a/jdk/test/java/net/InetAddress/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-Simple1NameServiceDescriptor
-Simple2NameServiceDescriptor
--- a/jdk/test/java/net/InetAddress/Simple1NameServiceDescriptor.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- */
-
-import sun.net.spi.nameservice.*;
-
-
-public class Simple1NameServiceDescriptor implements NameServiceDescriptor {
-    public NameService createNameService() {
-        SimpleNameService ns = new SimpleNameService();
-
-        // both providers know this host, but the address is different
-        ns.put("blade", "10.0.0.1");
-        // only this provider knows this host
-        ns.put("blade.domain1", "10.0.0.2");
-
-        return ns;
-    }
-
-    public String getProviderName() {
-        return "sun";
-    }
-
-    public String getType() {
-        return "simple1";
-    }
-}
--- a/jdk/test/java/net/InetAddress/Simple2NameServiceDescriptor.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- */
-
-import sun.net.spi.nameservice.*;
-
-
-public class Simple2NameServiceDescriptor implements NameServiceDescriptor {
-    public NameService createNameService() {
-        SimpleNameService ns = new SimpleNameService();
-        // both providers know this host, but the address of it is different
-        ns.put("blade", "20.0.0.1");
-        // only this provider knows this host
-        ns.put("blade.domain2", "20.0.0.2");
-
-        return ns;
-    }
-
-    public String getProviderName() {
-        return "sun";
-    }
-
-    public String getType() {
-        return "simple2";
-    }
-}
--- a/jdk/test/java/net/InetAddress/SimpleNameService.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- */
-
-import java.net.*;
-import java.util.*;
-import sun.net.spi.nameservice.*;
-
-
-public class SimpleNameService implements NameService {
-    // host name <-> host addr mapping
-    private HashMap<String, String> hosts = new LinkedHashMap<String, String>();
-
-    public void put(String host, String addr) {
-        hosts.put(host, addr);
-    }
-
-    private static String addrToString(byte addr[]) {
-        return Byte.toString(addr[0]) + "." +
-               Byte.toString(addr[1]) + "." +
-               Byte.toString(addr[2]) + "." +
-               Byte.toString(addr[3]);
-    }
-
-    public SimpleNameService() {
-    }
-
-    public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
-        String addr = hosts.get(host);
-        if (addr == null) {
-            throw new UnknownHostException(host);
-        }
-
-        StringTokenizer tokenizer = new StringTokenizer(addr, ".");
-        byte addrs[] = new byte[4];
-        for (int i = 0; i < 4; i++) {
-            addrs[i] = (byte)Integer.parseInt(tokenizer.nextToken());
-        }
-        InetAddress[] ret = new InetAddress[1];
-        ret[0] = InetAddress.getByAddress(host, addrs);
-        return ret;
-    }
-
-    public String getHostByAddr(byte[] addr) throws UnknownHostException {
-        String addrString = addrToString(addr);
-        Iterator i = hosts.keySet().iterator();
-        while (i.hasNext()) {
-            String host = (String)i.next();
-            String value = (String)hosts.get(host);
-            if (value.equals(addrString)) {
-                return host;
-            }
-        }
-        throw new UnknownHostException();
-    }
-}
--- a/jdk/test/sun/net/InetAddress/nameservice/B6442088.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6442088
- * @summary Change default DNS caching behavior for code not running under
- *          security manager.
- *
- * @build B6442088 SimpleNameService SimpleNameServiceDescriptor
- * @run main/othervm/timeout=200 -Dsun.net.inetaddr.ttl=20 -Dsun.net.spi.nameservice.provider.1=simple,sun B6442088
- */
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.Security;
-
-public class B6442088 {
-
-    public static void main(String args[]) throws Exception {
-
-        // name service needs to resolve this.
-        SimpleNameService.put("theclub", "129.156.220.219");
-
-        test ("theclub", "129.156.220.219", true);      // lk: 1
-        test ("luster", "1.16.20.2", false);            // lk: 2
-
-        // name service now needs to know about luster
-        SimpleNameService.put("luster", "10.5.18.21");
-
-        test ("luster", "1.16.20.2", false);            // lk: 2
-        sleep (10+1);
-        test("luster", "10.5.18.21", true, 3);          // lk: 3
-        sleep (5);
-
-        SimpleNameService.put("foo", "10.5.18.22");
-        SimpleNameService.put("theclub", "129.156.220.1");
-
-        test ("theclub", "129.156.220.219", true, 3);
-        test ("luster", "10.5.18.21", true, 3);
-        test ("bar", "10.5.18.22", false, 4);
-        test ("foo", "10.5.18.22", true, 5);
-
-        // now delay to see if theclub has expired
-        sleep (5);
-
-        test ("foo", "10.5.18.22", true, 5);
-        test ("theclub", "129.156.220.1", true, 6);
-
-        sleep (11);
-        // now see if luster has expired
-        test ("luster", "10.5.18.21", true, 7);
-        test ("theclub", "129.156.220.1", true, 7);
-
-        // now delay to see if 3rd has expired
-        sleep (10+6);
-
-        test ("theclub", "129.156.220.1", true, 8);
-        test ("luster", "10.5.18.21", true, 8);
-        test ("foo", "10.5.18.22", true, 9);
-    }
-
-    /* throws RuntimeException if it fails */
-
-    static void test (String host, String address,
-                        boolean shouldSucceed, int count) {
-        test (host, address, shouldSucceed);
-        int got = SimpleNameService.lookupCalls();
-        if (got != count) {
-            throw new RuntimeException ("lookups exp/got: " + count+"/"+got);
-        }
-    }
-
-    static void sleep (int seconds) {
-        try {
-            Thread.sleep (seconds * 1000);
-        } catch (InterruptedException e) {}
-    }
-
-    static void test (String host, String address, boolean shouldSucceed) {
-        InetAddress addr = null;
-        try {
-            addr = InetAddress.getByName (host);
-            if (!shouldSucceed) {
-                throw new RuntimeException (host+":"+address+": should fail");
-
-            }
-            if (!address.equals(addr.getHostAddress())) {
-                throw new RuntimeException(host+":"+address+": compare failed");
-            }
-        } catch (UnknownHostException e) {
-            if (shouldSucceed) {
-                throw new RuntimeException(host+":"+address+": should succeed");
-            }
-        }
-    }
-
-}
--- a/jdk/test/sun/net/InetAddress/nameservice/CacheTest.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4292867
- * @summary Check that InetAddress doesn't continue to throw UHE
- *          after the name service has recovered and the negative ttl
- *          on the initial lookup has expired.
- *
- * @build CacheTest SimpleNameService SimpleNameServiceDescriptor
- * @run main/othervm/timeout=200 -Dsun.net.spi.nameservice.provider.1=simple,sun CacheTest
- */
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.Security;
-
-public class CacheTest {
-
-
-    public static void main(String args[]) throws Exception {
-
-        /*
-         * First check the ttl on negative lookups is in the <15 second
-         * range. If the ttl is <=0 it means we cache forever or always
-         * consult the name service. For ttl > 15 the test would take
-         * too long so we skip it (need to coordinate jtreg timeout
-         * with negative ttl)
-         */
-        String ttlProp = "networkaddress.cache.negative.ttl";
-        int ttl = 0;
-        String policy = Security.getProperty(ttlProp);
-        if (policy != null) {
-            ttl = Integer.parseInt(policy);
-        }
-        if (ttl <= 0  || ttl > 15) {
-            System.err.println("Security property " + ttlProp + " needs to " +
-                " in 1-15 second range to execute this test");
-            return;
-
-        }
-
-        /*
-         * The following outlines how the test works :-
-         *
-         * 1. Do a lookup via InetAddress.getByName that it guaranteed
-         *    to succeed. This forces at least one entry into the cache
-         *    that will not expire.
-         *
-         * 2. Do a lookup via InetAddress.getByName that is guarnateed
-         *    to fail. This results in a negative lookup cached for
-         *    for a short period to time.
-         *
-         * 3. Wait for the cache entry to expire.
-         *
-         * 4. Do a lookup (which should consult the name service) and
-         *    the lookup should succeed.
-         */
-
-        // name service needs to resolve this.
-        SimpleNameService.put("theclub", "129.156.220.219");
-
-        // this lookup will succeed
-        InetAddress.getByName("theclub");
-
-        // lookup "luster" - this should throw UHE as name service
-        // doesn't know anything about this host.
-
-        try {
-            InetAddress.getByName("luster");
-            throw new RuntimeException("Test internal error " +
-                " - luster is bring resolved by name service");
-        } catch (UnknownHostException x) {
-        }
-
-        // name service now needs to know about luster
-        SimpleNameService.put("luster", "10.5.18.21");
-
-        // wait for the cache entry to expire and lookup should
-        // succeed.
-        Thread.currentThread().sleep(ttl*1000 + 1000);
-        InetAddress.getByName("luster");
-    }
-
-}
--- a/jdk/test/sun/net/InetAddress/nameservice/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# name service provider descriptor
-SimpleNameServiceDescriptor
--- a/jdk/test/sun/net/InetAddress/nameservice/SimpleNameService.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * A simple name service based on an in-memory HashMap.
- */
-import java.net.UnknownHostException;
-import java.net.InetAddress;
-import sun.net.spi.nameservice.*;
-import java.util.*;
-
-public final class SimpleNameService implements NameService {
-
-    private static LinkedHashMap hosts = new LinkedHashMap();
-
-    private static String addrToString(byte addr[]) {
-        return Byte.toString(addr[0]) + "." +
-               Byte.toString(addr[1]) + "." +
-               Byte.toString(addr[2]) + "." +
-               Byte.toString(addr[3]);
-    }
-
-    // ------------
-
-    public static void put(String host, String addr) {
-        hosts.put(host, addr);
-    }
-
-    public static void put(String host, byte addr[]) {
-        hosts.put(host, addrToString(addr));
-    }
-
-    public static void remove(String host) {
-        hosts.remove(host);
-    }
-
-    public static int entries () {
-        return hosts.size();
-    }
-
-    public static int lookupCalls() {
-        return lookupCalls;
-    }
-
-    static int lookupCalls = 0;
-
-    // ------------
-
-    public SimpleNameService() throws Exception {
-    }
-
-    public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
-
-        lookupCalls ++;
-
-        String value = (String)hosts.get(host);
-        if (value == null) {
-            throw new UnknownHostException(host);
-        }
-        StringTokenizer st = new StringTokenizer(value, ".");
-        byte addr[] = new byte[4];
-        for (int i=0; i<4; i++) {
-            addr[i] = (byte)Integer.parseInt(st.nextToken());
-        }
-        InetAddress[] res = new InetAddress[1];
-        res[0] = InetAddress.getByAddress(host, addr);
-        return res;
-    }
-
-    public String getHostByAddr(byte[] addr) throws UnknownHostException {
-        String addrString = addrToString(addr);
-        Iterator i = hosts.keySet().iterator();
-        while (i.hasNext()) {
-            String host = (String)i.next();
-            String value = (String)hosts.get(host);
-            if (value.equals(addrString)) {
-                return host;
-            }
-        }
-        throw new UnknownHostException();
-    }
-}
--- a/jdk/test/sun/net/InetAddress/nameservice/SimpleNameServiceDescriptor.java	Thu Jan 20 15:23:57 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Descriptor for the simple name service
- */
-import sun.net.spi.nameservice.*;
-
-public final class SimpleNameServiceDescriptor implements NameServiceDescriptor {
-    /**
-     * Create a new instance of the corresponding name service.
-     */
-    public NameService createNameService() throws Exception {
-        return new SimpleNameService();
-    }
-
-    /**
-     * Returns this service provider's name
-     *
-     */
-    public String getProviderName() {
-        return "sun";
-    }
-
-    /**
-     * Returns this name service type
-     * "dns" "nis" etc
-     */
-    public String getType() {
-        return "simple";
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/chaining/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions
+
+Simple1NameServiceDescriptor
+Simple2NameServiceDescriptor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/chaining/Providers.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4762344
+ * @summary 2nd nameservice provider is non functional
+ * @compile -XDignore.symbol.file=true SimpleNameService.java
+ *                                     Simple1NameServiceDescriptor.java
+ *                                     Simple2NameServiceDescriptor.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=simple1,sun -Dsun.net.spi.nameservice.provider.2=simple2,sun Providers
+ */
+
+import java.net.*;
+import java.util.*;
+
+
+public class Providers {
+    private static String[][] hostnames = new String[][] {
+            // both providers know this host, but with different address
+            new String[] {"blade", "10.0.0.1"},
+            // provider1 knwos this host
+            new String[] {"blade.domain1", "10.0.0.2"},
+            // provider2 knows this host
+            new String[] {"blade.domain2", "20.0.0.2"}
+        };
+    private static String[][] hostaddrs = new String[][] {
+            new String[] {"10.0.0.1", "blade"},
+            new String[] {"10.0.0.2", "blade.domain1"},
+            new String[] {"20.0.0.2", "blade.domain2"}
+        };
+
+    public static void main(String[] args) throws Exception {
+        for (int i = 0; i < hostnames.length; i++) {
+            doLookup(hostnames[i][0], hostnames[i][1]);
+        }
+        for (int i = 0; i < hostaddrs.length; i++) {
+            doReverseLookup(hostaddrs[i][0], hostaddrs[i][1]);
+        }
+    }
+
+    private static void doLookup(String host, String addr) throws Exception {
+        String res = InetAddress.getByName(host).getHostAddress();
+        if (!res.equals(addr)) {
+            throw new RuntimeException("Test failed: wrong address for host " + host);
+        }
+    }
+
+    private static void doReverseLookup(String addr, String host) throws Exception {
+        StringTokenizer tokenizer = new StringTokenizer(addr, ".");
+        byte addrs[] = new byte[4];
+        for (int i = 0; i < 4; i++) {
+            addrs[i] = (byte)Integer.parseInt(tokenizer.nextToken());
+        }
+        String res = InetAddress.getByAddress(addrs).getHostName();
+        if (!res.equals(host)) {
+            throw new RuntimeException("Test failed: wrong host name for address " + addr);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/chaining/Simple1NameServiceDescriptor.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ */
+
+import sun.net.spi.nameservice.*;
+
+
+public class Simple1NameServiceDescriptor implements NameServiceDescriptor {
+    public NameService createNameService() {
+        SimpleNameService ns = new SimpleNameService();
+
+        // both providers know this host, but the address is different
+        ns.put("blade", "10.0.0.1");
+        // only this provider knows this host
+        ns.put("blade.domain1", "10.0.0.2");
+
+        return ns;
+    }
+
+    public String getProviderName() {
+        return "sun";
+    }
+
+    public String getType() {
+        return "simple1";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/chaining/Simple2NameServiceDescriptor.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ */
+
+import sun.net.spi.nameservice.*;
+
+
+public class Simple2NameServiceDescriptor implements NameServiceDescriptor {
+    public NameService createNameService() {
+        SimpleNameService ns = new SimpleNameService();
+        // both providers know this host, but the address of it is different
+        ns.put("blade", "20.0.0.1");
+        // only this provider knows this host
+        ns.put("blade.domain2", "20.0.0.2");
+
+        return ns;
+    }
+
+    public String getProviderName() {
+        return "sun";
+    }
+
+    public String getType() {
+        return "simple2";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/chaining/SimpleNameService.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ */
+
+import java.net.*;
+import java.util.*;
+import sun.net.spi.nameservice.*;
+
+
+public class SimpleNameService implements NameService {
+    // host name <-> host addr mapping
+    private HashMap<String, String> hosts = new LinkedHashMap<String, String>();
+
+    public void put(String host, String addr) {
+        hosts.put(host, addr);
+    }
+
+    private static String addrToString(byte addr[]) {
+        return Byte.toString(addr[0]) + "." +
+               Byte.toString(addr[1]) + "." +
+               Byte.toString(addr[2]) + "." +
+               Byte.toString(addr[3]);
+    }
+
+    public SimpleNameService() {
+    }
+
+    public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
+        String addr = hosts.get(host);
+        if (addr == null) {
+            throw new UnknownHostException(host);
+        }
+
+        StringTokenizer tokenizer = new StringTokenizer(addr, ".");
+        byte addrs[] = new byte[4];
+        for (int i = 0; i < 4; i++) {
+            addrs[i] = (byte)Integer.parseInt(tokenizer.nextToken());
+        }
+        InetAddress[] ret = new InetAddress[1];
+        ret[0] = InetAddress.getByAddress(host, addrs);
+        return ret;
+    }
+
+    public String getHostByAddr(byte[] addr) throws UnknownHostException {
+        String addrString = addrToString(addr);
+        Iterator i = hosts.keySet().iterator();
+        while (i.hasNext()) {
+            String host = (String)i.next();
+            String value = (String)hosts.get(host);
+            if (value.equals(addrString)) {
+                return host;
+            }
+        }
+        throw new UnknownHostException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/deadlock/Hang.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 7012768
+ * @compile -XDignore.symbol.file=true ThrowingNameService.java
+ *          ThrowingNameServiceDescriptor.java
+ * @run main/othervm/timeout=30 -Dsun.net.spi.nameservice.provider.1=throwing,sun Hang
+ * @summary InetAddress lookupTable leaks/deadlocks when using unsupported
+ *          name service spi
+ */
+
+import java.net.InetAddress;
+
+public class Hang {
+    public static void main(String[] args) throws Exception {
+        try {
+            // 1st attempt - IllegalStateException caught below
+            InetAddress.getByName("host.company.com");
+        } catch (IllegalStateException e) { }
+
+        // 2nd attempt - Stuck here forever if bug exists
+        InetAddress.getByName("host.company.com");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/deadlock/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+ThrowingNameServiceDescriptor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameService.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import sun.net.spi.nameservice.NameService;
+
+public class ThrowingNameService implements NameService {
+    static boolean firstCall = true;
+
+    @Override
+    public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
+        if (firstCall) {
+            firstCall = false;
+            // throw unchecked exception first time round
+            throw new IllegalStateException();
+        }
+
+        // return any valid address
+        return new InetAddress[] { InetAddress.getLoopbackAddress() };
+    }
+
+    @Override
+    public String getHostByAddr(byte[] addr) throws UnknownHostException {
+        throw new IllegalStateException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/deadlock/ThrowingNameServiceDescriptor.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import sun.net.spi.nameservice.*;
+
+public class ThrowingNameServiceDescriptor implements NameServiceDescriptor {
+    public NameService createNameService() {
+        return new ThrowingNameService();
+    }
+
+    @Override
+    public String getProviderName() {
+        return "sun";
+    }
+
+    @Override
+    public String getType() {
+        return "throwing";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/simple/CacheTest.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4292867
+ * @summary Check that InetAddress doesn't continue to throw UHE
+ *          after the name service has recovered and the negative ttl
+ *          on the initial lookup has expired.
+ * @compile -XDignore.symbol.file=true SimpleNameService.java
+ *                                     SimpleNameServiceDescriptor.java
+ * @run main/othervm/timeout=200 -Dsun.net.spi.nameservice.provider.1=simple,sun CacheTest
+ */
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.Security;
+
+public class CacheTest {
+
+
+    public static void main(String args[]) throws Exception {
+
+        /*
+         * First check the ttl on negative lookups is in the <15 second
+         * range. If the ttl is <=0 it means we cache forever or always
+         * consult the name service. For ttl > 15 the test would take
+         * too long so we skip it (need to coordinate jtreg timeout
+         * with negative ttl)
+         */
+        String ttlProp = "networkaddress.cache.negative.ttl";
+        int ttl = 0;
+        String policy = Security.getProperty(ttlProp);
+        if (policy != null) {
+            ttl = Integer.parseInt(policy);
+        }
+        if (ttl <= 0  || ttl > 15) {
+            System.err.println("Security property " + ttlProp + " needs to " +
+                " in 1-15 second range to execute this test");
+            return;
+
+        }
+
+        /*
+         * The following outlines how the test works :-
+         *
+         * 1. Do a lookup via InetAddress.getByName that it guaranteed
+         *    to succeed. This forces at least one entry into the cache
+         *    that will not expire.
+         *
+         * 2. Do a lookup via InetAddress.getByName that is guarnateed
+         *    to fail. This results in a negative lookup cached for
+         *    for a short period to time.
+         *
+         * 3. Wait for the cache entry to expire.
+         *
+         * 4. Do a lookup (which should consult the name service) and
+         *    the lookup should succeed.
+         */
+
+        // name service needs to resolve this.
+        SimpleNameService.put("theclub", "129.156.220.219");
+
+        // this lookup will succeed
+        InetAddress.getByName("theclub");
+
+        // lookup "luster" - this should throw UHE as name service
+        // doesn't know anything about this host.
+
+        try {
+            InetAddress.getByName("luster");
+            throw new RuntimeException("Test internal error " +
+                " - luster is bring resolved by name service");
+        } catch (UnknownHostException x) {
+        }
+
+        // name service now needs to know about luster
+        SimpleNameService.put("luster", "10.5.18.21");
+
+        // wait for the cache entry to expire and lookup should
+        // succeed.
+        Thread.currentThread().sleep(ttl*1000 + 1000);
+        InetAddress.getByName("luster");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/simple/DefaultCaching.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6442088
+ * @summary Change default DNS caching behavior for code not running under
+ *          security manager.
+ * @compile -XDignore.symbol.file=true SimpleNameService.java
+ *                                     SimpleNameServiceDescriptor.java
+ * @run main/othervm/timeout=200 -Dsun.net.inetaddr.ttl=20 -Dsun.net.spi.nameservice.provider.1=simple,sun DefaultCaching
+ */
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.Security;
+
+public class DefaultCaching {
+
+    public static void main(String args[]) throws Exception {
+
+        // name service needs to resolve this.
+        SimpleNameService.put("theclub", "129.156.220.219");
+
+        test ("theclub", "129.156.220.219", true);      // lk: 1
+        test ("luster", "1.16.20.2", false);            // lk: 2
+
+        // name service now needs to know about luster
+        SimpleNameService.put("luster", "10.5.18.21");
+
+        test ("luster", "1.16.20.2", false);            // lk: 2
+        sleep (10+1);
+        test("luster", "10.5.18.21", true, 3);          // lk: 3
+        sleep (5);
+
+        SimpleNameService.put("foo", "10.5.18.22");
+        SimpleNameService.put("theclub", "129.156.220.1");
+
+        test ("theclub", "129.156.220.219", true, 3);
+        test ("luster", "10.5.18.21", true, 3);
+        test ("bar", "10.5.18.22", false, 4);
+        test ("foo", "10.5.18.22", true, 5);
+
+        // now delay to see if theclub has expired
+        sleep (5);
+
+        test ("foo", "10.5.18.22", true, 5);
+        test ("theclub", "129.156.220.1", true, 6);
+
+        sleep (11);
+        // now see if luster has expired
+        test ("luster", "10.5.18.21", true, 7);
+        test ("theclub", "129.156.220.1", true, 7);
+
+        // now delay to see if 3rd has expired
+        sleep (10+6);
+
+        test ("theclub", "129.156.220.1", true, 8);
+        test ("luster", "10.5.18.21", true, 8);
+        test ("foo", "10.5.18.22", true, 9);
+    }
+
+    /* throws RuntimeException if it fails */
+
+    static void test (String host, String address,
+                        boolean shouldSucceed, int count) {
+        test (host, address, shouldSucceed);
+        int got = SimpleNameService.lookupCalls();
+        if (got != count) {
+            throw new RuntimeException ("lookups exp/got: " + count+"/"+got);
+        }
+    }
+
+    static void sleep (int seconds) {
+        try {
+            Thread.sleep (seconds * 1000);
+        } catch (InterruptedException e) {}
+    }
+
+    static void test (String host, String address, boolean shouldSucceed) {
+        InetAddress addr = null;
+        try {
+            addr = InetAddress.getByName (host);
+            if (!shouldSucceed) {
+                throw new RuntimeException (host+":"+address+": should fail");
+
+            }
+            if (!address.equals(addr.getHostAddress())) {
+                throw new RuntimeException(host+":"+address+": compare failed");
+            }
+        } catch (UnknownHostException e) {
+            if (shouldSucceed) {
+                throw new RuntimeException(host+":"+address+": should succeed");
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/simple/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+SimpleNameServiceDescriptor    # name service provider descriptor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameService.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * A simple name service based on an in-memory HashMap.
+ */
+import java.net.UnknownHostException;
+import java.net.InetAddress;
+import sun.net.spi.nameservice.*;
+import java.util.*;
+
+public final class SimpleNameService implements NameService {
+
+    private static LinkedHashMap hosts = new LinkedHashMap();
+
+    private static String addrToString(byte addr[]) {
+        return Byte.toString(addr[0]) + "." +
+               Byte.toString(addr[1]) + "." +
+               Byte.toString(addr[2]) + "." +
+               Byte.toString(addr[3]);
+    }
+
+    // ------------
+
+    public static void put(String host, String addr) {
+        hosts.put(host, addr);
+    }
+
+    public static void put(String host, byte addr[]) {
+        hosts.put(host, addrToString(addr));
+    }
+
+    public static void remove(String host) {
+        hosts.remove(host);
+    }
+
+    public static int entries () {
+        return hosts.size();
+    }
+
+    public static int lookupCalls() {
+        return lookupCalls;
+    }
+
+    static int lookupCalls = 0;
+
+    // ------------
+
+    public SimpleNameService() throws Exception {
+    }
+
+    public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
+
+        lookupCalls ++;
+
+        String value = (String)hosts.get(host);
+        if (value == null) {
+            throw new UnknownHostException(host);
+        }
+        StringTokenizer st = new StringTokenizer(value, ".");
+        byte addr[] = new byte[4];
+        for (int i=0; i<4; i++) {
+            addr[i] = (byte)Integer.parseInt(st.nextToken());
+        }
+        InetAddress[] res = new InetAddress[1];
+        res[0] = InetAddress.getByAddress(host, addr);
+        return res;
+    }
+
+    public String getHostByAddr(byte[] addr) throws UnknownHostException {
+        String addrString = addrToString(addr);
+        Iterator i = hosts.keySet().iterator();
+        while (i.hasNext()) {
+            String host = (String)i.next();
+            String value = (String)hosts.get(host);
+            if (value.equals(addrString)) {
+                return host;
+            }
+        }
+        throw new UnknownHostException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/InetAddress/nameservice/simple/SimpleNameServiceDescriptor.java	Fri Jan 21 17:02:57 2011 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Descriptor for the simple name service
+ */
+import sun.net.spi.nameservice.*;
+
+public final class SimpleNameServiceDescriptor implements NameServiceDescriptor {
+    /**
+     * Create a new instance of the corresponding name service.
+     */
+    public NameService createNameService() throws Exception {
+        return new SimpleNameService();
+    }
+
+    /**
+     * Returns this service provider's name
+     *
+     */
+    public String getProviderName() {
+        return "sun";
+    }
+
+    /**
+     * Returns this name service type
+     * "dns" "nis" etc
+     */
+    public String getType() {
+        return "simple";
+    }
+}