8026245: InetAddress.getLocalHost crash if IPv6 disabled (macosx)

Reviewed-by: chegar, alanb
diff --git a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
index 44f3b7a..6ef0aca4 100644
--- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
+++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
@@ -70,6 +70,8 @@
 
 
 #if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
+extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
+
 /* Use getaddrinfo(3), which is thread safe */
 /************************************************************************
  * Inet4AddressImpl
@@ -378,8 +380,6 @@
     return (*env)->NewStringUTF(env, hostname);
 }
 
-extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
-
 /*
  * Find an internet address for a given hostname.  Note that this
  * code only works for addresses of type INET. The translation
diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
index 9f81cf8..d83db70 100644
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
@@ -122,9 +122,11 @@
 static jclass ni_ia6cls;
 static jmethodID ni_ia4ctrID;
 static jmethodID ni_ia6ctrID;
+static jboolean preferIPv6Address;
 
 static void initializeInetClasses(JNIEnv *env)
 {
+    jfieldID ni_preferIPv6AddressID;
     static int initialized = 0;
     if (!initialized) {
         ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
@@ -135,6 +137,10 @@
         ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
         ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
         ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
+        ni_preferIPv6AddressID =
+            (*env)->GetStaticFieldID(env, ni_iacls, "preferIPv6Address", "Z");
+        preferIPv6Address =
+            (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
         initialized = 1;
     }
 }
@@ -145,7 +151,6 @@
 lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
 {
     jobjectArray result = NULL;
-    jboolean preferIPv6Address;
     char myhostname[NI_MAXHOST+1];
     struct ifaddrs *ifa = NULL;
     int familyOrder = 0;
@@ -157,9 +162,6 @@
     // Make sure static variables we need are set.
     initializeInetClasses(env);
 
-    /* get the address preference */
-    preferIPv6Address = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
-
     /* If the requested name matches this host's hostname, return IP addresses
      * from all attached interfaces. (#2844683 et al) This prevents undesired
      * PPP dialup, but may return addresses that don't actually correspond to
@@ -278,7 +280,6 @@
     const char *hostname;
     jobjectArray ret = 0;
     int retLen = 0;
-    jboolean preferIPv6Address;
 
     int error=0;
 #ifdef AF_INET6
@@ -296,36 +297,18 @@
 
 #ifdef MACOSX
     /*
-     * If getaddrinfo has failed and we're looking up the local machine, we
-     * attempt to get the address from getifaddrs. This ensures we get an
-     * IPv6 address for the local machine.
+     * If we're looking up the local machine, attempt to get the address
+     * from getifaddrs. This ensures we get an IPv6 address for the local
+     * machine.
      */
-    if (error) {
-        ret = lookupIfLocalhost(env, hostname, JNI_TRUE);
-        if (ret != NULL || (*env)->ExceptionCheck(env)) {
-            JNU_ReleaseStringPlatformChars(env, host, hostname);
-            return ret;
-        }
+    ret = lookupIfLocalhost(env, hostname, JNI_TRUE);
+    if (ret != NULL || (*env)->ExceptionCheck(env)) {
+        JNU_ReleaseStringPlatformChars(env, host, hostname);
+        return ret;
     }
 #endif
 
 #ifdef AF_INET6
-    static jfieldID ia_preferIPv6AddressID;
-    if (ia_preferIPv6AddressID == NULL) {
-        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-        if (c)  {
-            ia_preferIPv6AddressID =
-                (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
-        }
-        if (ia_preferIPv6AddressID == NULL) {
-            JNU_ReleaseStringPlatformChars(env, host, hostname);
-            return NULL;
-        }
-    }
-    /* get the address preference */
-    preferIPv6Address
-        = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
-
     /* Try once, with our static buffer. */
     memset(&hints, 0, sizeof(hints));
     hints.ai_flags = AI_CANONNAME;
diff --git a/jdk/test/java/net/InetAddress/GetLocalHostWithSM.java b/jdk/test/java/net/InetAddress/GetLocalHostWithSM.java
index c8d06ac..9701a74 100644
--- a/jdk/test/java/net/InetAddress/GetLocalHostWithSM.java
+++ b/jdk/test/java/net/InetAddress/GetLocalHostWithSM.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, 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
@@ -23,9 +23,11 @@
 
 /**
  * @test
- * @bug 4531817
+ * @bug 4531817 8026245
  * @summary Inet[46]Address.localHost need doPrivileged
  * @run main/othervm GetLocalHostWithSM
+ * @run main/othervm -Djava.net.preferIPv4Stack=true GetLocalHostWithSM
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true GetLocalHostWithSM
  * files needed: GetLocalHostWithSM.java, MyPrincipal.java, and policy.file
  */
 
diff --git a/jdk/test/java/net/Socket/GetLocalAddress.java b/jdk/test/java/net/Socket/GetLocalAddress.java
index 606ba64..e9573d2 100644
--- a/jdk/test/java/net/Socket/GetLocalAddress.java
+++ b/jdk/test/java/net/Socket/GetLocalAddress.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -23,7 +23,10 @@
 
 /*
  * @test
- * @bug 4106601
+ * @bug 4106601 8026245
+ * @run main/othervm GetLocalAddress
+ * @run main/othervm -Djava.net.preferIPv4Stack=true GetLocalAddress
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true GetLocalAddress
  * @summary Test the java.net.socket.GetLocalAddress method
  *
  */