0

We use jdk1.8. The exception is bellow:

Caused by: java.lang.NullPointerException
    at java.net.InetAddress$Cache.put(InetAddress.java:806)
    at java.net.InetAddress.cacheAddresses(InetAddress.java:885)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1362)
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
    at java.net.InetAddress.getAllByName(InetAddress.java:1192)
    at java.net.InetAddress.getAllByName(InetAddress.java:1126)
    at java.net.InetAddress.getByName(InetAddress.java:1076)
    at java.net.InetSocketAddress.<init>(InetSocketAddress.java:220)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:451)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:546)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
    at sun.net.www.http.HttpClient.New(HttpClient.java:326)
    at sun.net.www.http.HttpClient.New(HttpClient.java:345)
    ...........
    ...........

From the line 828,829, Cache will not pult null into the map.

However, InetAddress has use synchronized when cache the address.

So I don't know why there will throw a NullPointerException.

Attention, cache is managed by the InetAddress instead of user. I wonder why it will throw npe. It's improssible.

Related code is as follow:

InetAddress:

    // InetAddress
    private static void cacheAddresses(String hostname,
                                       InetAddress[] addresses,
                                       boolean success) {
        hostname = hostname.toLowerCase();
        synchronized (addressCache) {
            cacheInitIfNeeded();
            if (success) {
885                addressCache.put(hostname, addresses);
886            } else {
887                negativeCache.put(hostname, addresses);
            }
        }
    }


Cache:

      ublic Cache put(String host, InetAddress[] addresses) {
            int policy = getPolicy();
            if (policy == InetAddressCachePolicy.NEVER) {
                return this;
            }

            // purge any expired entries

            if (policy != InetAddressCachePolicy.FOREVER) {

                // As we iterate in insertion order we can
                // terminate when a non-expired entry is found.
                LinkedList<String> expired = new LinkedList<>();
                long now = System.currentTimeMillis();
                for (String key : cache.keySet()) {
                    CacheEntry entry = cache.get(key);

806                    if (entry.expiration >= 0 && entry.expiration < now) {
807                        expired.add(key);
808                    } else {
809                        break;
                    }
                }

                for (String key : expired) {
                    cache.remove(key);
                }
            }

            // create new entry and add it to the cache
            // -- as a HashMap replaces existing entries we
            //    don't need to explicitly check if there is
            //    already an entry for this host.
            long expiration;
            if (policy == InetAddressCachePolicy.FOREVER) {
                expiration = -1;
            } else {
                expiration = System.currentTimeMillis() + (policy * 1000);
            }
828            CacheEntry entry = new CacheEntry(addresses, expiration);
829            cache.put(host, entry);
830            return this;
        }
salexinx
  • 99
  • 1
  • 4
  • 1
    Is there a chance the cache could be corrupted by some other code in your system? Can you try running the code on a different JDK? Can you reliably reproduce this, and if so, what code/input does it happen with? Finally, if your post lacks details, **do not** paste "Stackoverflow said, etc.", those aren't details, it's spam. – Kayaman Oct 31 '19 at 07:12
  • @Kayaman 1. Is there a chance the cache could be corrupted by some other code in your system? No, the cache is managed by the InetAddress, nobody can modification in the same time. 2. Can you try running the code on a different JDK?Can you reliably reproduce this, and if so, what code/input does it happen with? Sorry, the machine only has one jdk version and the npe is not immediately appear. My question is why this will throw npe. The cache's modification in the InetAddress all has synchronized. – salexinx Oct 31 '19 at 07:57
  • 3. if your post lacks details, do not paste "Stackoverflow said, etc.", Sorry, For convenience, I copy the source code for the answers. – salexinx Oct 31 '19 at 08:01
  • The cache *could* be corrupted (through reflection for example), but it's not too likely. Are you connecting to a lot of different addresses? This is buggy behaviour, so that's what makes this question problematic. – Kayaman Oct 31 '19 at 10:09
  • @Kayaman Yes, there are several clients. They need get host's ip by InetAddress. And It's true that there might has one thread modify the cache. But I don't find it. – salexinx Oct 31 '19 at 12:55
  • Well, if you just want to avoid this happening, you could try using a different http client (such as apache's) to see if the problem persists. – Kayaman Oct 31 '19 at 12:57
  • @Kayaman Thanks a lot. I has use the singleton to avoid the problem. i just try to find the correct answer. – salexinx Oct 31 '19 at 13:05

0 Answers0