changeset 5887:7ca8a40795d8

8000724: Improve networking serialization Summary: delegate InetAddress fields to a holder object Reviewed-by: alanb, chegar
author michaelm
date Wed, 13 Feb 2013 10:47:15 +0000
parents 343ecd8dee6f
children d00ab6592b1e
files src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java src/share/classes/java/net/Inet4Address.java src/share/classes/java/net/Inet4AddressImpl.java src/share/classes/java/net/Inet6Address.java src/share/classes/java/net/Inet6AddressImpl.java src/share/classes/java/net/InetAddress.java src/share/classes/java/net/InetSocketAddress.java src/share/native/java/net/InetAddress.c src/share/native/java/net/net_util.c src/share/native/java/net/net_util.h src/solaris/native/java/net/Inet4AddressImpl.c src/solaris/native/java/net/Inet6AddressImpl.c src/solaris/native/java/net/NetworkInterface.c src/solaris/native/java/net/PlainDatagramSocketImpl.c src/solaris/native/java/net/net_util_md.c src/windows/native/java/net/Inet4AddressImpl.c src/windows/native/java/net/Inet6AddressImpl.c src/windows/native/java/net/NetworkInterface.c src/windows/native/java/net/NetworkInterface.h src/windows/native/java/net/NetworkInterface_winXP.c src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c src/windows/native/java/net/TwoStacksPlainSocketImpl.c src/windows/native/java/net/net_util_md.c
diffstat 23 files changed, 289 insertions(+), 223 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Wed Feb 13 10:47:15 2013 +0000
@@ -124,7 +124,7 @@
      * not connected already.
      */
     protected void disconnect() {
-        disconnect0(connectedAddress.family);
+        disconnect0(connectedAddress.holder().getFamily());
         connected = false;
         connectedAddress = null;
         connectedPort = -1;
--- a/src/share/classes/java/net/Inet4Address.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/Inet4Address.java	Wed Feb 13 10:47:15 2013 +0000
@@ -102,27 +102,28 @@
 
     Inet4Address() {
         super();
-        hostName = null;
-        address = 0;
-        family = IPv4;
+        holder().hostName = null;
+        holder().address = 0;
+        holder().family = IPv4;
     }
 
     Inet4Address(String hostName, byte addr[]) {
-        this.hostName = hostName;
-        this.family = IPv4;
+        holder().hostName = hostName;
+        holder().family = IPv4;
         if (addr != null) {
             if (addr.length == INADDRSZ) {
-                address  = addr[3] & 0xFF;
+                int address  = addr[3] & 0xFF;
                 address |= ((addr[2] << 8) & 0xFF00);
                 address |= ((addr[1] << 16) & 0xFF0000);
                 address |= ((addr[0] << 24) & 0xFF000000);
+                holder().address = address;
             }
         }
     }
     Inet4Address(String hostName, int address) {
-        this.hostName = hostName;
-        this.family = IPv4;
-        this.address = address;
+        holder().hostName = hostName;
+        holder().family = IPv4;
+        holder().address = address;
     }
 
     /**
@@ -136,8 +137,8 @@
     private Object writeReplace() throws ObjectStreamException {
         // will replace the to be serialized 'this' object
         InetAddress inet = new InetAddress();
-        inet.hostName = this.hostName;
-        inet.address = this.address;
+        inet.holder().hostName = holder().getHostName();
+        inet.holder().address = holder().getAddress();
 
         /**
          * Prior to 1.4 an InetAddress was created with a family
@@ -145,7 +146,7 @@
          * For compatibility reasons we must therefore write the
          * the InetAddress with this family.
          */
-        inet.family = 2;
+        inet.holder().family = 2;
 
         return inet;
     }
@@ -159,7 +160,7 @@
      * @since   JDK1.1
      */
     public boolean isMulticastAddress() {
-        return ((address & 0xf0000000) == 0xe0000000);
+        return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
     }
 
     /**
@@ -169,7 +170,7 @@
      * @since 1.4
      */
     public boolean isAnyLocalAddress() {
-        return address == 0;
+        return holder().getAddress() == 0;
     }
 
     /**
@@ -198,6 +199,7 @@
         // defined in "Documenting Special Use IPv4 Address Blocks
         // that have been Registered with IANA" by Bill Manning
         // draft-manning-dsua-06.txt
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 169)
             && (((address >>> 16) & 0xFF) == 254);
     }
@@ -214,6 +216,7 @@
         // 10/8 prefix
         // 172.16/12 prefix
         // 192.168/16 prefix
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 10)
             || ((((address >>> 24) & 0xFF) == 172)
                 && (((address >>> 16) & 0xF0) == 16))
@@ -260,6 +263,7 @@
      */
     public boolean isMCLinkLocal() {
         // 224.0.0/24 prefix and ttl == 1
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 224)
             && (((address >>> 16) & 0xFF) == 0)
             && (((address >>> 8) & 0xFF) == 0);
@@ -275,6 +279,7 @@
      */
     public boolean isMCSiteLocal() {
         // 239.255/16 prefix or ttl < 32
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 239)
             && (((address >>> 16) & 0xFF) == 255);
     }
@@ -290,6 +295,7 @@
      */
     public boolean isMCOrgLocal() {
         // 239.192 - 239.195
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 239)
             && (((address >>> 16) & 0xFF) >= 192)
             && (((address >>> 16) & 0xFF) <= 195);
@@ -303,6 +309,7 @@
      * @return  the raw IP address of this object.
      */
     public byte[] getAddress() {
+        int address = holder().getAddress();
         byte[] addr = new byte[INADDRSZ];
 
         addr[0] = (byte) ((address >>> 24) & 0xFF);
@@ -328,7 +335,7 @@
      * @return  a hash code value for this IP address.
      */
     public int hashCode() {
-        return address;
+        return holder().getAddress();
     }
 
     /**
@@ -349,7 +356,7 @@
      */
     public boolean equals(Object obj) {
         return (obj != null) && (obj instanceof Inet4Address) &&
-            (((InetAddress)obj).address == address);
+            (((InetAddress)obj).holder().getAddress() == holder().getAddress());
     }
 
     // Utilities
--- a/src/share/classes/java/net/Inet4AddressImpl.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/Inet4AddressImpl.java	Wed Feb 13 10:47:15 2013 +0000
@@ -40,7 +40,7 @@
     public synchronized InetAddress anyLocalAddress() {
         if (anyLocalAddress == null) {
             anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00}
-            anyLocalAddress.hostName = "0.0.0.0";
+            anyLocalAddress.holder().hostName = "0.0.0.0";
         }
         return anyLocalAddress;
     }
--- a/src/share/classes/java/net/Inet6Address.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/Inet6Address.java	Wed Feb 13 10:47:15 2013 +0000
@@ -213,18 +213,18 @@
 
     Inet6Address() {
         super();
-        hostName = null;
+        holder().hostName = null;
         ipaddress = new byte[INADDRSZ];
-        family = IPv6;
+        holder().family = IPv6;
     }
 
     /* checking of value for scope_id should be done by caller
      * scope_id must be >= 0, or -1 to indicate not being set
      */
     Inet6Address(String hostName, byte addr[], int scope_id) {
-        this.hostName = hostName;
+        holder().hostName = hostName;
         if (addr.length == INADDRSZ) { // normal IPv6 address
-            family = IPv6;
+            holder().family = IPv6;
             ipaddress = addr.clone();
         }
         if (scope_id >= 0) {
@@ -325,9 +325,9 @@
     }
 
     private void initif(String hostName, byte addr[],NetworkInterface nif) throws UnknownHostException {
-        this.hostName = hostName;
+        holder().hostName = hostName;
         if (addr.length == INADDRSZ) { // normal IPv6 address
-            family = IPv6;
+            holder().family = IPv6;
             ipaddress = addr.clone();
         }
         if (nif != null) {
@@ -412,6 +412,11 @@
         throws IOException, ClassNotFoundException {
         scope_ifname = null;
         scope_ifname_set = false;
+
+        if (getClass().getClassLoader() != null) {
+            throw new SecurityException ("invalid address type");
+        }
+
         s.defaultReadObject();
 
         if (ifname != null && !"".equals (ifname)) {
@@ -445,7 +450,7 @@
                                              ipaddress.length);
         }
 
-        if (family != IPv6) {
+        if (holder().getFamily() != IPv6) {
             throw new InvalidObjectException("invalid address family type");
         }
     }
--- a/src/share/classes/java/net/Inet6AddressImpl.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/Inet6AddressImpl.java	Wed Feb 13 10:47:15 2013 +0000
@@ -81,7 +81,7 @@
         if (anyLocalAddress == null) {
             if (InetAddress.preferIPv6Address) {
                 anyLocalAddress = new Inet6Address();
-                anyLocalAddress.hostName = "::";
+                anyLocalAddress.holder().hostName = "::";
             } else {
                 anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
             }
--- a/src/share/classes/java/net/InetAddress.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/InetAddress.java	Wed Feb 13 10:47:15 2013 +0000
@@ -34,8 +34,12 @@
 import java.util.ArrayList;
 import java.security.AccessController;
 import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
 import sun.security.action.*;
 import sun.net.InetAddressCachePolicy;
 import sun.net.util.IPAddressUtil;
@@ -199,25 +203,47 @@
     /* Specify address family preference */
     static transient boolean preferIPv6Address = false;
 
-    /**
-     * @serial
-     */
-    String hostName;
+    static class InetAddressHolder {
 
-    /**
-     * Holds a 32-bit IPv4 address.
-     *
-     * @serial
-     */
-    int address;
+        InetAddressHolder() {}
 
-    /**
-     * Specifies the address family type, for instance, '1' for IPv4
-     * addresses, and '2' for IPv6 addresses.
-     *
-     * @serial
-     */
-    int family;
+        InetAddressHolder(String hostName, int address, int family) {
+            this.hostName = hostName;
+            this.address = address;
+            this.family = family;
+        }
+
+        String hostName;
+
+        String getHostName() {
+            return hostName;
+        }
+
+        /**
+         * Holds a 32-bit IPv4 address.
+         */
+        int address;
+
+        int getAddress() {
+            return address;
+        }
+
+        /**
+         * Specifies the address family type, for instance, '1' for IPv4
+         * addresses, and '2' for IPv6 addresses.
+         */
+        int family;
+
+        int getFamily() {
+            return family;
+        }
+    }
+
+    final transient InetAddressHolder holder;
+
+    InetAddressHolder holder() {
+        return holder;
+    }
 
     /* Used to store the name service provider */
     private static List<NameService> nameServices = null;
@@ -245,6 +271,7 @@
      * put in the address cache, since it is not created by name.
      */
     InetAddress() {
+        holder = new InetAddressHolder();
     }
 
     /**
@@ -257,7 +284,7 @@
      */
     private Object readResolve() throws ObjectStreamException {
         // will replace the deserialized 'this' object
-        return new Inet4Address(this.hostName, this.address);
+        return new Inet4Address(holder().getHostName(), holder().getAddress());
     }
 
     /**
@@ -494,10 +521,10 @@
      * @see SecurityManager#checkConnect
      */
     String getHostName(boolean check) {
-        if (hostName == null) {
-            hostName = InetAddress.getHostFromNameService(this, check);
+        if (holder().getHostName() == null) {
+            holder().hostName = InetAddress.getHostFromNameService(this, check);
         }
-        return hostName;
+        return holder().getHostName();
     }
 
     /**
@@ -660,6 +687,7 @@
      * @return  a string representation of this IP address.
      */
     public String toString() {
+        String hostName = holder().getHostName();
         return ((hostName != null) ? hostName : "")
             + "/" + getHostAddress();
     }
@@ -1515,14 +1543,58 @@
         }
     }
 
+    private static final long FIELDS_OFFSET;
+    private static final sun.misc.Unsafe UNSAFE;
+
+    static {
+        try {
+            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            FIELDS_OFFSET = unsafe.objectFieldOffset(
+                InetAddress.class.getDeclaredField("holder")
+            );
+            UNSAFE = unsafe;
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
     private void readObject (ObjectInputStream s) throws
                          IOException, ClassNotFoundException {
-        s.defaultReadObject ();
         if (getClass().getClassLoader() != null) {
-            hostName = null;
-            address = 0;
             throw new SecurityException ("invalid address type");
         }
+        GetField gf = s.readFields();
+        String host = (String)gf.get("hostName", null);
+        int address= gf.get("address", 0);
+        int family= gf.get("family", 0);
+        InetAddressHolder h = new InetAddressHolder(host, address, family);
+        UNSAFE.putObject(this, FIELDS_OFFSET, h);
+    }
+
+    /* needed because the serializable fields no longer exist */
+
+    /**
+     * @serialField hostName String
+     * @serialField address int
+     * @serialField family int
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("hostName", String.class),
+        new ObjectStreamField("address", int.class),
+        new ObjectStreamField("family", int.class),
+    };
+
+    private void writeObject (ObjectOutputStream s) throws
+                        IOException {
+        if (getClass().getClassLoader() != null) {
+            throw new SecurityException ("invalid address type");
+        }
+        PutField pf = s.putFields();
+        pf.put("hostName", holder().hostName);
+        pf.put("address", holder().address);
+        pf.put("family", holder().family);
+        s.writeFields();
+        s.flush();
     }
 }
 
--- a/src/share/classes/java/net/InetSocketAddress.java	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/classes/java/net/InetSocketAddress.java	Wed Feb 13 10:47:15 2013 +0000
@@ -87,8 +87,8 @@
             if (hostname != null)
                 return hostname;
             if (addr != null) {
-                if (addr.hostName != null)
-                    return addr.hostName;
+                if (addr.holder().getHostName() != null)
+                    return addr.holder().getHostName();
                 else
                     return addr.getHostAddress();
             }
--- a/src/share/native/java/net/InetAddress.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/native/java/net/InetAddress.c	Wed Feb 13 10:47:15 2013 +0000
@@ -33,8 +33,11 @@
  */
 
 jclass ia_class;
-jfieldID ia_addressID;
-jfieldID ia_familyID;
+jclass iac_class;
+jfieldID ia_holderID;
+jfieldID iac_addressID;
+jfieldID iac_familyID;
+jfieldID iac_hostNameID;
 jfieldID ia_preferIPv6AddressID;
 
 /*
@@ -48,10 +51,18 @@
     CHECK_NULL(c);
     ia_class = (*env)->NewGlobalRef(env, c);
     CHECK_NULL(ia_class);
-    ia_addressID = (*env)->GetFieldID(env, ia_class, "address", "I");
-    CHECK_NULL(ia_addressID);
-    ia_familyID = (*env)->GetFieldID(env, ia_class, "family", "I");
-    CHECK_NULL(ia_familyID);
+    c = (*env)->FindClass(env,"java/net/InetAddress$InetAddressHolder");
+    CHECK_NULL(c);
+    iac_class = (*env)->NewGlobalRef(env, c);
+    ia_holderID = (*env)->GetFieldID(env, ia_class, "holder", "Ljava/net/InetAddress$InetAddressHolder;");
+    CHECK_NULL(ia_holderID);
     ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "Z");
     CHECK_NULL(ia_preferIPv6AddressID);
+
+    iac_addressID = (*env)->GetFieldID(env, iac_class, "address", "I");
+    CHECK_NULL(iac_addressID);
+    iac_familyID = (*env)->GetFieldID(env, iac_class, "family", "I");
+    CHECK_NULL(iac_familyID);
+    iac_hostNameID = (*env)->GetFieldID(env, iac_class, "hostName", "Ljava/lang/String;");
+    CHECK_NULL(iac_hostNameID);
 }
--- a/src/share/native/java/net/net_util.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/native/java/net/net_util.c	Wed Feb 13 10:47:15 2013 +0000
@@ -84,6 +84,58 @@
     }
 }
 
+/* The address, and family fields used to be in InetAddress
+ * but are now in an implementation object. So, there is an extra
+ * level of indirection to access them now.
+ */
+
+extern jclass iac_class;
+extern jfieldID ia_holderID;
+extern jfieldID iac_addressID;
+extern jfieldID iac_familyID;
+
+void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetIntField(env, holder, iac_addressID, address);
+}
+
+void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetIntField(env, holder, iac_familyID, family);
+}
+
+void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetObjectField(env, holder, iac_hostNameID, host);
+}
+
+int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetIntField(env, holder, iac_addressID);
+}
+
+int getInetAddress_family(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetIntField(env, holder, iac_familyID);
+}
+
+jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetObjectField(env, holder, iac_hostNameID);
+}
+
 JNIEXPORT jobject JNICALL
 NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
     jobject iaObj;
@@ -110,8 +162,8 @@
             iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
             CHECK_NULL_RETURN(iaObj, NULL);
             address = NET_IPv4MappedToIPv4(caddr);
-            (*env)->SetIntField(env, iaObj, ia_addressID, address);
-            (*env)->SetIntField(env, iaObj, ia_familyID, IPv4);
+            setInetAddress_addr(env, iaObj, address);
+            setInetAddress_family(env, iaObj, IPv4);
         } else {
             static jclass inet6Cls = 0;
             jint scope;
@@ -131,7 +183,7 @@
 
             (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
 
-            (*env)->SetIntField(env, iaObj, ia_familyID, IPv6);
+            setInetAddress_family(env, iaObj, IPv6);
             scope = getScopeID(him);
             (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
             if (scope > 0)
@@ -153,9 +205,8 @@
             }
             iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
             CHECK_NULL_RETURN(iaObj, NULL);
-            (*env)->SetIntField(env, iaObj, ia_familyID, IPv4);
-            (*env)->SetIntField(env, iaObj, ia_addressID,
-                                ntohl(him4->sin_addr.s_addr));
+            setInetAddress_family(env, iaObj, IPv4);
+            setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
             *port = ntohs(him4->sin_port);
         }
     return iaObj;
@@ -167,8 +218,7 @@
     jint family = AF_INET;
 
 #ifdef AF_INET6
-    family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4?
-        AF_INET : AF_INET6;
+    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
     if (him->sa_family == AF_INET6) {
 #ifdef WIN32
         struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
@@ -183,7 +233,7 @@
                 return JNI_FALSE;
             }
             addrNew = NET_IPv4MappedToIPv4(caddrNew);
-            addrCur = (*env)->GetIntField(env, iaObj, ia_addressID);
+            addrCur = getInetAddress_addr(env, iaObj);
             if (addrNew == addrCur) {
                 return JNI_TRUE;
             } else {
@@ -215,7 +265,7 @@
                 return JNI_FALSE;
             }
             addrNew = ntohl(him4->sin_addr.s_addr);
-            addrCur = (*env)->GetIntField(env, iaObj, ia_addressID);
+            addrCur = getInetAddress_addr(env, iaObj);
             if (addrNew == addrCur) {
                 return JNI_TRUE;
             } else {
--- a/src/share/native/java/net/net_util.h	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/share/native/java/net/net_util.h	Wed Feb 13 10:47:15 2013 +0000
@@ -53,10 +53,18 @@
  * i.e. psi_timeoutID is PlainSocketImpl's timeout field's ID.
  */
 extern jclass ia_class;
-extern jfieldID ia_addressID;
-extern jfieldID ia_familyID;
+extern jfieldID iac_addressID;
+extern jfieldID iac_familyID;
+extern jfieldID iac_hostNameID;
 extern jfieldID ia_preferIPv6AddressID;
 
+extern void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address);
+extern void setInetAddress_family(JNIEnv *env, jobject iaObj, int family);
+extern void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject h);
+extern int getInetAddress_addr(JNIEnv *env, jobject iaObj);
+extern int getInetAddress_family(JNIEnv *env, jobject iaObj);
+extern jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj);
+
 extern jclass ia4_class;
 extern jmethodID ia4_ctrID;
 
--- a/src/solaris/native/java/net/Inet4AddressImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/solaris/native/java/net/Inet4AddressImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -102,9 +102,6 @@
 static jclass ni_iacls;
 static jclass ni_ia4cls;
 static jmethodID ni_ia4ctrID;
-static jfieldID ni_iaaddressID;
-static jfieldID ni_iahostID;
-static jfieldID ni_iafamilyID;
 static int initialized = 0;
 
 /*
@@ -135,9 +132,6 @@
       ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
       ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
       ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
-      ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
-      ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
-      ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
       initialized = 1;
     }
 
@@ -238,9 +232,8 @@
                 ret = NULL;
                 goto cleanupAndReturn;
             }
-            (*env)->SetIntField(env, iaObj, ni_iaaddressID,
-                                ntohl(((struct sockaddr_in*)(iterator->ai_addr))->sin_addr.s_addr));
-            (*env)->SetObjectField(env, iaObj, ni_iahostID, name);
+            setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)(iterator->ai_addr))->sin_addr.s_addr));
+            setInetAddress_hostName(env, iaObj, name);
             (*env)->SetObjectArrayElement(env, ret, retLen - i -1, iaObj);
             i++;
             iterator = iterator->ai_next;
@@ -395,9 +388,6 @@
 static jclass ni_iacls;
 static jclass ni_ia4cls;
 static jmethodID ni_ia4ctrID;
-static jfieldID ni_iaaddressID;
-static jfieldID ni_iahostID;
-static jfieldID ni_iafamilyID;
 static int initialized = 0;
 
 /*
@@ -431,9 +421,6 @@
       ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
       ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
       ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
-      ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
-      ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
-      ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
       initialized = 1;
     }
 
@@ -502,9 +489,8 @@
             ret = NULL;
             goto cleanupAndReturn;
           }
-          (*env)->SetIntField(env, iaObj, ni_iaaddressID,
-                              ntohl((*addrp)->s_addr));
-          (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+          setInetAddress_addr(env, iaObj, ntohl((*addrp)->s_addr));
+          setInetAddress_hostName(env, iaObj, host);
           (*env)->SetObjectArrayElement(env, ret, i, iaObj);
           addrp++;
           i++;
--- a/src/solaris/native/java/net/Inet6AddressImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/solaris/native/java/net/Inet6AddressImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -122,9 +122,6 @@
 static jclass ni_ia6cls;
 static jmethodID ni_ia4ctrID;
 static jmethodID ni_ia6ctrID;
-static jfieldID ni_iaaddressID;
-static jfieldID ni_iahostID;
-static jfieldID ni_iafamilyID;
 static jfieldID ni_ia6ipaddressID;
 static int initialized = 0;
 
@@ -161,9 +158,6 @@
       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_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
-      ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
-      ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
       ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
       initialized = 1;
     }
@@ -318,9 +312,8 @@
                   ret = NULL;
                   goto cleanupAndReturn;
                 }
-                (*env)->SetIntField(env, iaObj, ni_iaaddressID,
-                                    ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
-                (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+                setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
+                setInetAddress_hostName(env, iaObj, host);
                 (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
                 inetIndex++;
               } else if (iterator->ai_family == AF_INET6) {
@@ -351,7 +344,7 @@
                   (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
                 }
                 (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
-                (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+                setInetAddress_hostName(env, iaObj, host);
                 (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
                 inet6Index++;
               }
--- a/src/solaris/native/java/net/NetworkInterface.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/solaris/native/java/net/NetworkInterface.c	Wed Feb 13 10:47:15 2013 +0000
@@ -118,8 +118,6 @@
 static jmethodID ni_ia4ctrID;
 static jmethodID ni_ia6ctrID;
 static jmethodID ni_ibctrID;
-static jfieldID ni_iaaddressID;
-static jfieldID ni_iafamilyID;
 static jfieldID ni_ia6ipaddressID;
 static jfieldID ni_ibaddressID;
 static jfieldID ni_ib4broadcastID;
@@ -195,8 +193,6 @@
     ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
     ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
     ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
-    ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
-    ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
     ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
     ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
     ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
@@ -300,7 +296,7 @@
     netif *ifs, *curr;
 
 #ifdef AF_INET6
-    int family = (  (*env)->GetIntField(env, iaObj, ni_iafamilyID) == IPv4 ) ? AF_INET : AF_INET6;
+    int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6;
 #else
     int family =  AF_INET;
 #endif
@@ -325,7 +321,7 @@
             if (family == addrP->family) {
                 if (family == AF_INET) {
                     int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);
-                    int address2 = (*env)->GetIntField(env, iaObj, ni_iaaddressID);
+                    int address2 = getInetAddress_addr(env, iaObj);
 
                     if (address1 == address2) {
                         match = JNI_TRUE;
@@ -650,7 +646,7 @@
         if (addrP->family == AF_INET) {
             iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
             if (iaObj) {
-                 (*env)->SetIntField(env, iaObj, ni_iaaddressID, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
+                 setInetAddress_addr(env, iaObj, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
             }
             ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
             if (ibObj) {
@@ -659,8 +655,7 @@
                     jobject ia2Obj = NULL;
                     ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
                     if (ia2Obj) {
-                       (*env)->SetIntField(env, ia2Obj, ni_iaaddressID,
-                                                               htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
+                       setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
                        (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
                        (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
                     }
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -616,14 +616,13 @@
 
     iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
 #ifdef AF_INET6
-    family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4?
-        AF_INET : AF_INET6;
+    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
 #else
     family = AF_INET;
 #endif
     if (family == AF_INET) { /* this api can't handle IPV6 addresses */
-        int address = (*env)->GetIntField(env, iaObj, ia_addressID);
-        (*env)->SetIntField(env, addressObj, ia_addressID, address);
+        int address = getInetAddress_addr(env, iaObj);
+        setInetAddress_addr(env, addressObj, address);
     }
     return port;
 }
@@ -1170,23 +1169,18 @@
  */
 static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject value) {
     static jfieldID ni_addrsID;
-    static jfieldID ia_addressID;
     struct in_addr in;
     jobjectArray addrArray;
     jsize len;
     jobject addr;
     int i;
 
-    if (ni_addrsID == NULL || ia_addressID == NULL) {
+    if (ni_addrsID == NULL ) {
         jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
         CHECK_NULL(c);
         ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
                                         "[Ljava/net/InetAddress;");
         CHECK_NULL(ni_addrsID);
-        c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL(c);
-        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-        CHECK_NULL(ia_addressID);
     }
 
     addrArray = (*env)->GetObjectField(env, value, ni_addrsID);
@@ -1207,8 +1201,8 @@
      */
     for (i = 0; i < len; i++) {
         addr = (*env)->GetObjectArrayElement(env, addrArray, i);
-        if ((*env)->GetIntField(env, addr, ia_familyID) == IPv4) {
-            in.s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
+        if (getInetAddress_family(env, addr) == IPv4) {
+            in.s_addr = htonl(getInetAddress_addr(env, addr));
             break;
         }
     }
@@ -1268,17 +1262,9 @@
  * Throw exception if failed.
  */
 static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) {
-    static jfieldID ia_addressID;
     struct in_addr in;
 
-    if (ia_addressID == NULL) {
-        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL(c);
-        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-        CHECK_NULL(ia_addressID);
-    }
-
-    in.s_addr = htonl( (*env)->GetIntField(env, value, ia_addressID) );
+    in.s_addr = htonl( getInetAddress_addr(env, value) );
 
     if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
                        (const char*)&in, sizeof(in)) < 0) {
@@ -1629,7 +1615,6 @@
     if (isIPV4) {
         static jclass inet4_class;
         static jmethodID inet4_ctrID;
-        static jfieldID inet4_addrID;
 
         static jclass ni_class;
         static jmethodID ni_ctrID;
@@ -1667,8 +1652,6 @@
             CHECK_NULL_RETURN(c, NULL);
             inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
             CHECK_NULL_RETURN(inet4_ctrID, NULL);
-            inet4_addrID = (*env)->GetFieldID(env, c, "address", "I");
-            CHECK_NULL_RETURN(inet4_addrID, NULL);
             inet4_class = (*env)->NewGlobalRef(env, c);
             CHECK_NULL_RETURN(inet4_class, NULL);
         }
@@ -1676,10 +1659,10 @@
         CHECK_NULL_RETURN(addr, NULL);
 
 #ifdef __linux__
-        (*env)->SetIntField(env, addr, inet4_addrID,
-                (isOldKernel ? ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr)) );
+        setInetAddress_addr(env, addr, (isOldKernel ?
+                ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr)));
 #else
-        (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
+        setInetAddress_addr(env, addr, ntohl(in.s_addr));
 #endif
 
         /*
@@ -2164,7 +2147,7 @@
     ipv6_join_leave = ipv6_available();
 
 #ifdef __linux__
-    if ((*env)->GetIntField(env, iaObj, ia_familyID) == IPv4) {
+    if (getInetAddress_family(env, iaObj) == IPv4) {
         ipv6_join_leave = JNI_FALSE;
     }
 #endif
@@ -2211,7 +2194,7 @@
                     CHECK_NULL(ni_indexID);
                 }
 
-                mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID));
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
                 mname.imr_address.s_addr = 0;
                 mname.imr_ifindex =  (*env)->GetIntField(env, niObj, ni_indexID);
                 mname_len = sizeof(struct ip_mreqn);
@@ -2229,11 +2212,11 @@
                 }
                 addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
 
-                mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID));
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
 #ifdef __linux__
-                mname.imr_address.s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
+                mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr));
 #else
-                mname.imr_interface.s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
+                mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr));
 #endif
                 mname_len = sizeof(struct ip_mreq);
             }
@@ -2272,7 +2255,7 @@
                     }
                 }
 
-                mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID));
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
                 mname.imr_address.s_addr = 0 ;
                 mname.imr_ifindex = index;
                 mname_len = sizeof(struct ip_mreqn);
@@ -2302,7 +2285,7 @@
 #else
                 mname.imr_interface.s_addr = in.s_addr;
 #endif
-                mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID));
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
                 mname_len = sizeof(struct ip_mreq);
             }
         }
@@ -2367,10 +2350,10 @@
         jbyte caddr[16];
         jint family;
         jint address;
-        family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4? AF_INET : AF_INET6;
+        family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
         if (family == AF_INET) { /* will convert to IPv4-mapped address */
             memset((char *) caddr, 0, 16);
-            address = (*env)->GetIntField(env, iaObj, ia_addressID);
+            address = getInetAddress_addr(env, iaObj);
 
             caddr[10] = 0xff;
             caddr[11] = 0xff;
--- a/src/solaris/native/java/net/net_util_md.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/solaris/native/java/net/net_util_md.c	Wed Feb 13 10:47:15 2013 +0000
@@ -818,7 +818,7 @@
 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him,
                           int *len, jboolean v4MappedAddress) {
     jint family;
-    family = (*env)->GetIntField(env, iaObj, ia_familyID);
+    family = getInetAddress_family(env, iaObj);
 #ifdef AF_INET6
     /* needs work. 1. family 2. clean up him6 etc deallocate memory */
     if (ipv6_available() && !(family == IPv4 && v4MappedAddress == JNI_FALSE)) {
@@ -830,7 +830,7 @@
 
         if (family == IPv4) { /* will convert to IPv4-mapped address */
             memset((char *) caddr, 0, 16);
-            address = (*env)->GetIntField(env, iaObj, ia_addressID);
+            address = getInetAddress_addr(env, iaObj);
             if (address == INADDR_ANY) {
                 /* we would always prefer IPv6 wildcard address
                    caddr[10] = 0xff;
@@ -942,7 +942,7 @@
               return -1;
             }
             memset((char *) him4, 0, sizeof(struct sockaddr_in));
-            address = (*env)->GetIntField(env, iaObj, ia_addressID);
+            address = getInetAddress_addr(env, iaObj);
             him4->sin_port = htons((short) port);
             him4->sin_addr.s_addr = (uint32_t) htonl(address);
             him4->sin_family = AF_INET;
--- a/src/windows/native/java/net/Inet4AddressImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/Inet4AddressImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -114,9 +114,6 @@
 static jclass ni_iacls;
 static jclass ni_ia4cls;
 static jmethodID ni_ia4ctrID;
-static jfieldID ni_iaaddressID;
-static jfieldID ni_iahostID;
-static jfieldID ni_iafamilyID;
 static int initialized = 0;
 
 /*
@@ -149,9 +146,6 @@
       ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
       ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
       ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
-      ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
-      ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
-      ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
       initialized = 1;
     }
 
@@ -208,8 +202,7 @@
           ret = NULL;
           goto cleanupAndReturn;
         }
-        (*env)->SetIntField(env, iaObj, ni_iaaddressID,
-                            ntohl(address));
+        setInetAddress_addr(env, iaObj, ntohl(address));
         (*env)->SetObjectArrayElement(env, ret, 0, iaObj);
         JNU_ReleaseStringPlatformChars(env, host, hostname);
         return ret;
@@ -242,9 +235,8 @@
             ret = NULL;
             goto cleanupAndReturn;
           }
-          (*env)->SetIntField(env, iaObj, ni_iaaddressID,
-                              ntohl((*addrp)->s_addr));
-          (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+          setInetAddress_addr(env, iaObj, ntohl((*addrp)->s_addr));
+          setInetAddress_hostName(env, iaObj, host);
           (*env)->SetObjectArrayElement(env, ret, i, iaObj);
           addrp++;
           i++;
--- a/src/windows/native/java/net/Inet6AddressImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/Inet6AddressImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -77,9 +77,6 @@
 static jclass ni_ia6cls;
 static jmethodID ni_ia4ctrID;
 static jmethodID ni_ia6ctrID;
-static jfieldID ni_iaaddressID;
-static jfieldID ni_iahostID;
-static jfieldID ni_iafamilyID;
 static jfieldID ni_ia6ipaddressID;
 static int initialized = 0;
 
@@ -104,9 +101,6 @@
       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_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
-      ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
-      ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
       ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
       initialized = 1;
     }
@@ -243,9 +237,8 @@
                 ret = NULL;
                 goto cleanupAndReturn;
               }
-              (*env)->SetIntField(env, iaObj, ni_iaaddressID,
-                                  ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
-              (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+              setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
+              setInetAddress_hostName(env, iaObj, host);
               (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
                 inetIndex ++;
             } else if (iterator->ai_family == AF_INET6) {
@@ -269,7 +262,7 @@
                 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
               }
               (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
-              (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+              setInetAddress_hostName(env, iaObj, host);
               (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
               inet6Index ++;
             }
--- a/src/windows/native/java/net/NetworkInterface.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/NetworkInterface.c	Wed Feb 13 10:47:15 2013 +0000
@@ -66,7 +66,6 @@
 jfieldID ni_displayNameID;  /* NetworkInterface.displayName */
 jfieldID ni_childsID;       /* NetworkInterface.childs */
 jclass ni_iacls;            /* InetAddress */
-jfieldID ni_iaAddr;         /* InetAddress.address */
 
 jclass ni_ia4cls;           /* Inet4Address */
 jmethodID ni_ia4Ctor;       /* Inet4Address() */
@@ -445,7 +444,6 @@
 
     ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
     ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
-    ni_iaAddr = (*env)->GetFieldID(env, ni_iacls, "address", "I");
 
     ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
     ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
@@ -534,7 +532,7 @@
             }
             /* default ctor will set family to AF_INET */
 
-            (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr));
+            setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
             if (addrs->mask != -1) {
               ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
               if (ibObj == NULL) {
@@ -547,8 +545,7 @@
                 free_netaddr(netaddrP);
                 return NULL;
               }
-              (*env)->SetIntField(env, ia2Obj, ni_iaAddr,
-                                  ntohl(addrs->brdcast.him4.sin_addr.s_addr));
+              setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
               (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
               (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
               (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
@@ -702,7 +699,7 @@
     (JNIEnv *env, jclass cls, jobject iaObj)
 {
     netif *ifList, *curr;
-    jint addr = (*env)->GetIntField(env, iaObj, ni_iaAddr);
+    jint addr = getInetAddress_addr(env, iaObj);
     jobject netifObj = NULL;
 
     // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
--- a/src/windows/native/java/net/NetworkInterface.h	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/NetworkInterface.h	Wed Feb 13 10:47:15 2013 +0000
@@ -71,7 +71,6 @@
 extern jfieldID ni_childsID;        /* NetworkInterface.childs */
 
 extern jclass ni_iacls;             /* InetAddress */
-extern jfieldID ni_iaAddr;          /* InetAddress.address */
 
 extern jclass ni_ia4cls;            /* Inet4Address */
 extern jmethodID ni_ia4Ctor;        /* Inet4Address() */
--- a/src/windows/native/java/net/NetworkInterface_winXP.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/NetworkInterface_winXP.c	Wed Feb 13 10:47:15 2013 +0000
@@ -33,6 +33,7 @@
 #include "jni_util.h"
 
 #include "NetworkInterface.h"
+#include "net_util.h"
 
 /*
  * Windows implementation of the java.net.NetworkInterface native methods.
@@ -479,7 +480,7 @@
             }
             /* default ctor will set family to AF_INET */
 
-            (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr));
+            setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
 
             ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
             if (ibObj == NULL) {
@@ -492,8 +493,7 @@
               free_netaddr(netaddrP);
               return NULL;
             }
-            (*env)->SetIntField(env, ia2Obj, ni_iaAddr,
-                                ntohl(addrs->brdcast.him4.sin_addr.s_addr));
+            setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
             (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
             (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
             (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
--- a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -432,7 +432,7 @@
     int lcladdrlen;
     int address;
 
-    family = (*env)->GetIntField(env, addressObj, ia_familyID);
+    family = getInetAddress_family(env, addressObj);
     if (family == IPv6 && !ipv6_supported) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
@@ -452,7 +452,7 @@
         JNU_ThrowNullPointerException(env, "argument address");
         return;
     } else {
-        address = (*env)->GetIntField(env, addressObj, ia_addressID);
+        address = getInetAddress_addr(env, addressObj);
     }
 
     if (NET_InetAddressToSockaddr(env, addressObj, port, (struct sockaddr *)&lcladdr, &lcladdrlen, JNI_FALSE) != 0) {
@@ -552,9 +552,9 @@
         return;
     }
 
-    addr = (*env)->GetIntField(env, address, ia_addressID);
+    addr = getInetAddress_addr(env, address);
 
-    family = (*env)->GetIntField(env, address, ia_familyID);
+    family = getInetAddress_family(env, address);
     if (family == IPv6 && !ipv6_supported) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
@@ -670,7 +670,7 @@
         return;
     }
 
-    family = (*env)->GetIntField(env, iaObj, ia_familyID);
+    family = getInetAddress_family(env, iaObj);
     if (family == IPv4) {
         fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
     } else {
@@ -714,7 +714,7 @@
         if (!w2k_or_later) { /* avoid this check on Win 2K or better. Does not work with IPv6.
                       * Check is not necessary on these OSes */
             if (connected) {
-                address = (*env)->GetIntField(env, iaObj, ia_addressID);
+                address = getInetAddress_addr(env, iaObj);
             } else {
                 address = ntohl(rmtaddr.him4.sin_addr.s_addr);
             }
@@ -823,7 +823,7 @@
     if (IS_NULL(addressObj)) {
         JNU_ThrowNullPointerException(env, "Null address in peek()");
     } else {
-        address = (*env)->GetIntField(env, addressObj, ia_addressID);
+        address = getInetAddress_addr(env, addressObj);
         /* We only handle IPv4 for now. Will support IPv6 once its in the os */
         family = AF_INET;
     }
@@ -905,9 +905,8 @@
         JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", 0);
         return 0;
     }
-    (*env)->SetIntField(env, addressObj, ia_addressID,
-                        ntohl(remote_addr.sin_addr.s_addr));
-    (*env)->SetIntField(env, addressObj, ia_familyID, IPv4);
+    setInetAddress_addr(env, addressObj, ntohl(remote_addr.sin_addr.s_addr));
+    setInetAddress_family(env, addressObj, IPv4);
 
     /* return port */
     return ntohs(remote_addr.sin_port);
@@ -1574,21 +1573,16 @@
 {
     jobjectArray addrArray;
     static jfieldID ni_addrsID=0;
-    static jfieldID ia_familyID=0;
     jsize len;
     jobject addr;
     int i;
 
-    if (ni_addrsID == NULL || ia_familyID == NULL) {
+    if (ni_addrsID == NULL ) {
         jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
         CHECK_NULL_RETURN (c, -1);
         ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
                                         "[Ljava/net/InetAddress;");
         CHECK_NULL_RETURN (ni_addrsID, -1);
-        c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL_RETURN (c, -1);
-        ia_familyID = (*env)->GetFieldID(env, c, "family", "I");
-        CHECK_NULL_RETURN (ia_familyID, -1);
     }
 
     addrArray = (*env)->GetObjectField(env, nif, ni_addrsID);
@@ -1606,7 +1600,7 @@
     for (i=0; i<len; i++) {
         int fam;
         addr = (*env)->GetObjectArrayElement(env, addrArray, i);
-        fam = (*env)->GetIntField(env, addr, ia_familyID);
+        fam = getInetAddress_family(env, addr);
         if (fam == family) {
             *iaddr = addr;
             return 0;
@@ -1618,20 +1612,13 @@
 static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr)
 {
     jobject addr;
-    static jfieldID ia_addressID;
 
     int ret = getInetAddrFromIf (env, IPv4, nif, &addr);
     if (ret == -1) {
         return -1;
     }
 
-    if (ia_addressID == 0) {
-        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL_RETURN (c, -1);
-        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-        CHECK_NULL_RETURN (ia_addressID, -1);
-    }
-    iaddr->s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
+    iaddr->s_addr = htonl(getInetAddress_addr(env, addr));
     return 0;
 }
 
@@ -1706,17 +1693,9 @@
             }
             opt = java_net_SocketOptions_IP_MULTICAST_IF2;
         } else {
-            static jfieldID ia_addressID;
             struct in_addr in;
 
-            if (ia_addressID == NULL) {
-                        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-                CHECK_NULL(c);
-                ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-                CHECK_NULL(ia_addressID);
-            }
-
-            in.s_addr = htonl((*env)->GetIntField(env, value, ia_addressID));
+            in.s_addr = htonl(getInetAddress_addr(env, value));
 
             if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
                                (const char*)&in, sizeof(in)) < 0) {
@@ -1945,7 +1924,6 @@
     if (isIPV4) {
         static jclass inet4_class;
         static jmethodID inet4_ctrID;
-        static jfieldID inet4_addrID;
 
         static jclass ni_class;
         static jmethodID ni_ctrID;
@@ -1975,15 +1953,13 @@
             CHECK_NULL_RETURN(c, NULL);
             inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
             CHECK_NULL_RETURN(inet4_ctrID, NULL);
-            inet4_addrID = (*env)->GetFieldID(env, c, "address", "I");
-            CHECK_NULL_RETURN(inet4_addrID, NULL);
             inet4_class = (*env)->NewGlobalRef(env, c);
             CHECK_NULL_RETURN(inet4_class, NULL);
         }
         addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
         CHECK_NULL_RETURN(addr, NULL);
 
-        (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
+        setInetAddress_addr(env, addr, ntohl(in.s_addr));
 
         /*
          * For IP_MULTICAST_IF return InetAddress
--- a/src/windows/native/java/net/TwoStacksPlainSocketImpl.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/TwoStacksPlainSocketImpl.c	Wed Feb 13 10:47:15 2013 +0000
@@ -412,7 +412,7 @@
     fdObj = (*env)->GetObjectField(env, this, psi_fdID);
     fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
 
-    family = (*env)->GetIntField(env, iaObj, ia_familyID);
+    family = getInetAddress_family(env, iaObj);
 
     if (family == IPv6 && !ipv6_supported) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -724,9 +724,8 @@
             return;
         }
 
-        (*env)->SetIntField(env, socketAddressObj, ia_addressID,
-                            ntohl(him.him4.sin_addr.s_addr));
-        (*env)->SetIntField(env, socketAddressObj, ia_familyID, IPv4);
+        setInetAddress_addr(env, socketAddressObj, ntohl(him.him4.sin_addr.s_addr));
+        setInetAddress_family(env, socketAddressObj, IPv4);
         (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
     } else {
         jbyteArray addr;
@@ -754,7 +753,7 @@
         }
         addr = (*env)->GetObjectField (env, socketAddressObj, ia6_ipaddressID);
         (*env)->SetByteArrayRegion (env, addr, 0, 16, (const char *)&him.him6.sin6_addr);
-        (*env)->SetIntField(env, socketAddressObj, ia_familyID, IPv6);
+        setInetAddress_family(env, socketAddressObj, IPv6);
         (*env)->SetIntField(env, socketAddressObj, ia6_scopeidID, him.him6.sin6_scope_id);
     }
     /* fields common to AF_INET and AF_INET6 */
--- a/src/windows/native/java/net/net_util_md.c	Fri Feb 08 18:06:56 2013 +0400
+++ b/src/windows/native/java/net/net_util_md.c	Wed Feb 13 10:47:15 2013 +0000
@@ -804,7 +804,7 @@
 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him,
                           int *len, jboolean v4MappedAddress) {
     jint family, iafam;
-    iafam = (*env)->GetIntField(env, iaObj, ia_familyID);
+    iafam = getInetAddress_family(env, iaObj);
     family = (iafam == IPv4)? AF_INET : AF_INET6;
     if (ipv6_available() && !(family == AF_INET && v4MappedAddress == JNI_FALSE)) {
         struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
@@ -815,7 +815,7 @@
 
         if (family == AF_INET) { /* will convert to IPv4-mapped address */
             memset((char *) caddr, 0, 16);
-            address = (*env)->GetIntField(env, iaObj, ia_addressID);
+            address = getInetAddress_addr(env, iaObj);
             if (address == INADDR_ANY) {
                 /* we would always prefer IPv6 wildcard address
                 caddr[10] = 0xff;
@@ -854,7 +854,7 @@
           return -1;
         }
         memset((char *) him4, 0, sizeof(struct sockaddr_in));
-        address = (int)(*env)->GetIntField(env, iaObj, ia_addressID);
+        address = getInetAddress_addr(env, iaObj);
         him4->sin_port = htons((short) port);
         him4->sin_addr.s_addr = (u_long) htonl(address);
         him4->sin_family = AF_INET;