changeset 807:408c9c621938 jdk-9+142

8164908: ReflectionFactory support for IIOP and custom serialization Summary: Update IIOP Streams to use ReflectionFactory and Unsafe Reviewed-by: alanb, chegar, plevart, amlu
author rriggs
date Mon, 24 Oct 2016 14:53:29 -0400
parents 089356ac3c69
children 6211236ef15e
files src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java src/java.corba/share/classes/module-info.java src/java.corba/share/classes/sun/corba/Bridge.java src/java.corba/share/classes/sun/corba/SharedSecrets.java
diffstat 6 files changed, 236 insertions(+), 415 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java	Thu Oct 20 18:38:08 2016 +0000
+++ b/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java	Mon Oct 24 14:53:29 2016 -0400
@@ -31,22 +31,17 @@
 
 package com.sun.corba.se.impl.io;
 
-import java.io.InputStream;
 import java.io.IOException;
 import java.io.StreamCorruptedException;
 import java.io.ObjectInputValidation;
 import java.io.NotActiveException;
 import java.io.InvalidObjectException;
 import java.io.InvalidClassException;
-import java.io.DataInputStream;
 import java.io.OptionalDataException;
-import java.io.WriteAbortedException;
 import java.io.Externalizable;
 import java.io.EOFException;
 import java.lang.reflect.*;
 import java.util.Vector;
-import java.util.Stack;
-import java.util.Hashtable;
 import java.util.Enumeration;
 
 import sun.corba.Bridge ;
@@ -54,7 +49,6 @@
 import java.security.AccessController ;
 import java.security.PrivilegedAction ;
 
-import com.sun.corba.se.impl.io.ObjectStreamClass;
 import com.sun.corba.se.impl.util.Utility;
 
 import org.omg.CORBA.portable.ValueInputStream;
@@ -71,14 +65,12 @@
 import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
 import com.sun.org.omg.SendingContext.CodeBase;
 
-import javax.rmi.PortableRemoteObject;
 import javax.rmi.CORBA.Util;
 import javax.rmi.CORBA.ValueHandler;
 
 import java.security.*;
 import java.util.*;
 
-import com.sun.corba.se.impl.orbutil.ObjectUtility ;
 import com.sun.corba.se.impl.logging.OMGSystemException ;
 import com.sun.corba.se.impl.logging.UtilSystemException ;
 
@@ -182,75 +174,6 @@
 
     private byte streamFormatVersion;
 
-    // Since java.io.OptionalDataException's constructors are
-    // package private, but we need to throw it in some special
-    // cases, we try to do it by reflection.
-    private static final Constructor OPT_DATA_EXCEPTION_CTOR;
-
-    private Object[] readObjectArgList = { this } ;
-
-    static {
-        OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
-    }
-
-    // Grab the OptionalDataException boolean ctor and make
-    // it accessible.  Note that any exceptions
-    // will be wrapped in ExceptionInInitializerErrors.
-    private static Constructor getOptDataExceptionCtor() {
-
-        try {
-
-            Constructor result =
-
-                (Constructor) AccessController.doPrivileged(
-                                    new PrivilegedExceptionAction() {
-                    public java.lang.Object run()
-                        throws NoSuchMethodException,
-                        SecurityException {
-
-                        Constructor boolCtor
-                            = OptionalDataException.class.getDeclaredConstructor(
-                                                               new Class[] {
-                                Boolean.TYPE });
-
-                        boolCtor.setAccessible(true);
-
-                        return boolCtor;
-                    }});
-
-            if (result == null)
-                // XXX I18N, logging needed.
-                throw new Error("Unable to find OptionalDataException constructor");
-
-            return result;
-
-        } catch (Exception ex) {
-            // XXX I18N, logging needed.
-            throw new ExceptionInInitializerError(ex);
-        }
-    }
-
-    // Create a new OptionalDataException with the EOF marker
-    // set to true.  See handleOptionalDataMarshalException.
-    private OptionalDataException createOptionalDataException() {
-        try {
-            OptionalDataException result
-                = (OptionalDataException)
-                   OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] {
-                       Boolean.TRUE });
-
-            if (result == null)
-                // XXX I18N, logging needed.
-                throw new Error("Created null OptionalDataException");
-
-            return result;
-
-        } catch (Exception ex) {
-            // XXX I18N, logging needed.
-            throw new Error("Couldn't create OptionalDataException", ex);
-        }
-    }
-
     // Return the stream format version currently being used
     // to deserialize an object
     protected byte getStreamFormatVersion() {
@@ -395,7 +318,6 @@
                                   int offset)
                                          /* throws OptionalDataException, ClassNotFoundException, IOException */
     {
-
         /* Save the current state and get ready to read an object. */
         Object prevObject = currentObject;
         ObjectStreamClass prevClassDesc = currentClassDesc;
@@ -947,7 +869,7 @@
             if (!objectRead)
                 result = new EOFException("No more optional data");
             else
-                result = createOptionalDataException();
+                result = bridge.newOptionalDataExceptionForSerialization(true);
 
             result.initCause(marshalException);
 
@@ -1230,8 +1152,7 @@
 
                                 readObjectState.beginUnmarshalCustomValue(this,
                                                                           calledDefaultWriteObject,
-                                                                          (currentClassDesc.readObjectMethod
-                                                                           != null));
+                                                                          currentClassDesc.hasReadObject());
                             } else {
                                 if (currentClassDesc.hasReadObject())
                                     setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
@@ -1556,8 +1477,7 @@
 
                                 readObjectState.beginUnmarshalCustomValue(this,
                                                                           calledDefaultWriteObject,
-                                                                          (currentClassDesc.readObjectMethod
-                                                                           != null));
+                                                                          currentClassDesc.hasReadObject());
                             }
 
                             boolean usedReadObject = false;
@@ -1714,13 +1634,8 @@
         throws InvalidClassException, StreamCorruptedException,
                ClassNotFoundException, IOException
     {
-        if (osc.readObjectMethod == null) {
-            return false;
-        }
-
         try {
-            osc.readObjectMethod.invoke( obj, readObjectArgList ) ;
-            return true;
+            return osc.invokeReadObject( obj, this ) ;
         } catch (InvocationTargetException e) {
             Throwable t = e.getTargetException();
             if (t instanceof ClassNotFoundException)
@@ -1734,8 +1649,6 @@
             else
                 // XXX I18N, logging needed.
                 throw new Error("internal error");
-        } catch (IllegalAccessException e) {
-            return false;
         }
     }
 
--- a/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java	Thu Oct 20 18:38:08 2016 +0000
+++ b/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java	Mon Oct 24 14:53:29 2016 -0400
@@ -31,33 +31,23 @@
 
 package com.sun.corba.se.impl.io;
 
-import org.omg.CORBA.INTERNAL;
 import org.omg.CORBA.portable.OutputStream;
 
 import java.security.AccessController ;
 import java.security.PrivilegedAction ;
 
 import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.Serializable;
 import java.io.InvalidClassException;
-import java.io.StreamCorruptedException;
 import java.io.Externalizable;
-import java.io.ObjectStreamException;
 import java.io.NotSerializableException;
 import java.io.NotActiveException;
 
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Field;
-
-import java.util.Stack;
 
 import javax.rmi.CORBA.Util;
-import javax.rmi.CORBA.ValueHandlerMultiFormat;
 
 import sun.corba.Bridge ;
 
-import com.sun.corba.se.impl.io.ObjectStreamClass;
 import com.sun.corba.se.impl.util.Utility;
 import com.sun.corba.se.impl.util.RepositoryId;
 
@@ -621,7 +611,7 @@
             writeObjectState.enterWriteObject(this);
 
             // writeObject(obj, c, this);
-            osc.writeObjectMethod.invoke( obj, writeObjectArgList ) ;
+            osc.invokeWriteObject( obj, this ) ;
 
             writeObjectState.exitWriteObject(this);
 
@@ -636,8 +626,6 @@
             else
                 // XXX I18N, Logging needed.
                 throw new Error("invokeObjectWriter internal error",e);
-        } catch (IllegalAccessException e) {
-            // cannot happen
         }
     }
 
@@ -761,59 +749,52 @@
      */
     private void outputClassFields(Object o, Class cl,
                                    ObjectStreamField[] fields)
-        throws IOException, InvalidClassException {
+        throws IOException {
 
         for (int i = 0; i < fields.length; i++) {
             if (fields[i].getField() == null)
-                // XXX I18N, Logging needed.
                 throw new InvalidClassException(cl.getName(),
                                                 "Nonexistent field " + fields[i].getName());
-
-            try {
-                switch (fields[i].getTypeCode()) {
-                    case 'B':
-                        byte byteValue = fields[i].getField().getByte( o ) ;
-                        orbStream.write_octet(byteValue);
-                        break;
-                    case 'C':
-                        char charValue = fields[i].getField().getChar( o ) ;
-                        orbStream.write_wchar(charValue);
-                        break;
-                    case 'F':
-                        float floatValue = fields[i].getField().getFloat( o ) ;
-                        orbStream.write_float(floatValue);
-                        break;
-                    case 'D' :
-                        double doubleValue = fields[i].getField().getDouble( o ) ;
-                        orbStream.write_double(doubleValue);
-                        break;
-                    case 'I':
-                        int intValue = fields[i].getField().getInt( o ) ;
-                        orbStream.write_long(intValue);
-                        break;
-                    case 'J':
-                        long longValue = fields[i].getField().getLong( o ) ;
-                        orbStream.write_longlong(longValue);
-                        break;
-                    case 'S':
-                        short shortValue = fields[i].getField().getShort( o ) ;
-                        orbStream.write_short(shortValue);
-                        break;
-                    case 'Z':
-                        boolean booleanValue = fields[i].getField().getBoolean( o ) ;
-                        orbStream.write_boolean(booleanValue);
-                        break;
-                    case '[':
-                    case 'L':
-                        Object objectValue = fields[i].getField().get( o ) ;
-                        writeObjectField(fields[i], objectValue);
-                        break;
-                    default:
-                        // XXX I18N, Logging needed.
-                        throw new InvalidClassException(cl.getName());
-                }
-            } catch (IllegalAccessException exc) {
-                throw wrapper.illegalFieldAccess( exc, fields[i].getName() ) ;
+            switch (fields[i].getTypeCode()) {
+                case 'B':
+                    byte byteValue = bridge.getByte(o, fields[i].getFieldID()) ;
+                    orbStream.write_octet(byteValue);
+                    break;
+                case 'C':
+                    char charValue = bridge.getChar(o, fields[i].getFieldID()) ;
+                    orbStream.write_wchar(charValue);
+                    break;
+                case 'F':
+                    float floatValue = bridge.getFloat(o, fields[i].getFieldID()) ;
+                    orbStream.write_float(floatValue);
+                    break;
+                case 'D' :
+                    double doubleValue = bridge.getDouble(o, fields[i].getFieldID()) ;
+                    orbStream.write_double(doubleValue);
+                    break;
+                case 'I':
+                    int intValue = bridge.getInt(o, fields[i].getFieldID()) ;
+                    orbStream.write_long(intValue);
+                    break;
+                case 'J':
+                    long longValue = bridge.getLong(o, fields[i].getFieldID()) ;
+                    orbStream.write_longlong(longValue);
+                    break;
+                case 'S':
+                    short shortValue = bridge.getShort(o, fields[i].getFieldID()) ;
+                    orbStream.write_short(shortValue);
+                    break;
+                case 'Z':
+                    boolean booleanValue = bridge.getBoolean(o, fields[i].getFieldID()) ;
+                    orbStream.write_boolean(booleanValue);
+                    break;
+                case '[':
+                case 'L':
+                    Object objectValue = bridge.getObject(o, fields[i].getFieldID()) ;
+                    writeObjectField(fields[i], objectValue);
+                    break;
+                default:
+                    throw new InvalidClassException(cl.getName());
             }
         }
     }
--- a/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Thu Oct 20 18:38:08 2016 +0000
+++ b/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Mon Oct 24 14:53:29 2016 -0400
@@ -31,16 +31,16 @@
 
 package com.sun.corba.se.impl.io;
 
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandle;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.DigestOutputStream;
 import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
 import java.security.PrivilegedAction;
 
 import java.lang.reflect.Modifier;
-import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -80,9 +80,6 @@
 
     public static final long kDefaultUID = -1;
 
-    private static Object noArgsList[] = {};
-    private static Class<?> noTypesList[] = {};
-
     /** true if represents enum type */
     private boolean isEnum;
 
@@ -311,12 +308,37 @@
         return null;
     }
 
+    public final boolean invokeWriteObject(Object obj, ObjectOutputStream ois) throws InvocationTargetException {
+        if (!hasWriteObject()) {
+            return false;
+        }
+        try {
+            writeObjectMethod.invoke(obj, ois);
+        } catch (Throwable t) {
+            throw new InvocationTargetException(t, "writeObject");
+        }
+        return true;
+    }
+
+    public final boolean invokeReadObject(Object obj, ObjectInputStream ois) throws InvocationTargetException {
+        if (hasReadObject()) {
+            try {
+                readObjectMethod.invoke(obj, ois);
+                return true;
+            } catch (Throwable t) {
+                throw new InvocationTargetException(t, "readObject");
+            }
+        } else {
+            return false;
+        }
+    }
+
     public Serializable writeReplace(Serializable value) {
         if (writeReplaceObjectMethod != null) {
             try {
-                return (Serializable) writeReplaceObjectMethod.invoke(value,noArgsList);
-            } catch(Throwable t) {
-                throw new RuntimeException(t);
+                return (Serializable) writeReplaceObjectMethod.invoke(value);
+            } catch (Throwable t) {
+                throw new InternalError("unexpected error", t);
             }
         }
         else return value;
@@ -325,9 +347,9 @@
     public Object readResolve(Object value) {
         if (readResolveObjectMethod != null) {
             try {
-                return readResolveObjectMethod.invoke(value,noArgsList);
-            } catch(Throwable t) {
-                throw new RuntimeException(t);
+                return readResolveObjectMethod.invoke(value);
+            } catch (Throwable t) {
+                throw new InternalError("unexpected error", t);
             }
         }
         else return value;
@@ -382,31 +404,34 @@
          */
     }
 
-    private static final class PersistentFieldsValue
+    static final class PersistentFieldsValue
             extends ClassValue<ObjectStreamField[]> {
         PersistentFieldsValue() { }
 
         protected ObjectStreamField[] computeValue(Class<?> type) {
             try {
+                bridge.ensureClassInitialized(type);
                 Field pf = type.getDeclaredField("serialPersistentFields");
                 int mods = pf.getModifiers();
                 if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
                         Modifier.isFinal(mods)) {
-                    pf.setAccessible(true);
+                    long offset = bridge.staticFieldOffset(pf);
                     java.io.ObjectStreamField[] fields =
-                        (java.io.ObjectStreamField[])pf.get(type);
+                            (java.io.ObjectStreamField[])bridge.getObject(type, offset);
                     return translateFields(fields);
                 }
-            } catch (NoSuchFieldException | IllegalAccessException |
+            } catch (NoSuchFieldException |
                     IllegalArgumentException | ClassCastException e) {
             }
             return null;
         }
 
-        private static ObjectStreamField[] translateFields(
-            java.io.ObjectStreamField[] fields) {
+        private static ObjectStreamField[] translateFields(java.io.ObjectStreamField[] fields) {
+            if (fields == null) {
+                return null;
+            }
             ObjectStreamField[] translation =
-                new ObjectStreamField[fields.length];
+                    new ObjectStreamField[fields.length];
             for (int i = 0; i < fields.length; i++) {
                 translation[i] = new ObjectStreamField(fields[i].getName(),
                         fields[i].getType());
@@ -450,13 +475,11 @@
                  * If it is declared, use the declared serialPersistentFields.
                  * Otherwise, extract the fields from the class itself.
                  */
-                    fields = persistentFieldsValue.get(cl);
+                fields = persistentFieldsValue.get(cl);
 
                 if (fields == null) {
-                    /* Get all of the declared fields for this
-                     * Class. setAccessible on all fields so they
-                     * can be accessed later.  Create a temporary
-                     * ObjectStreamField array to hold each
+                    /* Get all of the declared fields for this Class.
+                     * Create a temporary ObjectStreamField array to hold each
                      * non-static, non-transient field. Then copy the
                      * temporary array into an array of the correct
                      * size once the number of fields is known.
@@ -471,7 +494,6 @@
                         int modifiers = fld.getModifiers();
                         if (!Modifier.isStatic(modifiers) &&
                             !Modifier.isTransient(modifiers)) {
-                            fld.setAccessible(true) ;
                             tempFields[numFields++] = new ObjectStreamField(fld);
                         }
                     }
@@ -487,7 +509,6 @@
                         try {
                             Field reflField = cl.getDeclaredField(fields[j].getName());
                             if (fields[j].getType() == reflField.getType()) {
-                                reflField.setAccessible(true);
                                 fields[j].setField(reflField);
                             }
                         } catch (NoSuchFieldException e) {
@@ -527,8 +548,8 @@
                         int mods = f.getModifiers();
                         // SerialBug 5:  static final SUID should be read
                         if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) {
-                            f.setAccessible(true);
-                            suid = f.getLong(cl);
+                            long offset = bridge.staticFieldOffset(f);
+                            suid = bridge.getLong(cl, offset);
                             // SerialBug 2: should be computed after writeObject
                             // actualSuid = computeStructuralUID(cl);
                         } else {
@@ -540,16 +561,12 @@
                         suid = _computeSerialVersionUID(cl);
                         // SerialBug 2: should be computed after writeObject
                         // actualSuid = computeStructuralUID(cl);
-                    } catch (IllegalAccessException ex) {
-                        suid = _computeSerialVersionUID(cl);
                     }
                 }
 
-                writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
-                    "writeReplace", noTypesList, Object.class);
+                writeReplaceObjectMethod = bridge.writeReplaceForSerialization(cl);
 
-                readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
-                    "readResolve", noTypesList, Object.class);
+                readResolveObjectMethod = bridge.readResolveForSerialization(cl);
 
                 if (externalizable)
                     cons = getExternalizableConstructor(cl) ;
@@ -557,14 +574,8 @@
                     cons = getSerializableConstructor(cl) ;
 
                 if (serializable && !forProxyClass) {
-                    /* Look for the writeObject method
-                     * Set the accessible flag on it here. ObjectOutputStream
-                     * will call it as necessary.
-                     */
-                    writeObjectMethod = getPrivateMethod( cl, "writeObject",
-                        new Class<?>[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ;
-                    readObjectMethod = getPrivateMethod( cl, "readObject",
-                        new Class<?>[] { java.io.ObjectInputStream.class }, Void.TYPE ) ;
+                    writeObjectMethod = bridge.writeObjectForSerialization(cl) ;
+                    readObjectMethod = bridge.readObjectForSerialization(cl);
                 }
                 return null;
             }
@@ -585,27 +596,6 @@
       }
     }
 
-    /**
-     * Returns non-static private method with given signature defined by given
-     * class, or null if none found.  Access checks are disabled on the
-     * returned method (if any).
-     */
-    private static Method getPrivateMethod(Class<?> cl, String name,
-                                           Class<?>[] argTypes,
-                                           Class<?> returnType)
-    {
-        try {
-            Method meth = cl.getDeclaredMethod(name, argTypes);
-            meth.setAccessible(true);
-            int mods = meth.getModifiers();
-            return ((meth.getReturnType() == returnType) &&
-                    ((mods & Modifier.STATIC) == 0) &&
-                    ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
-        } catch (NoSuchMethodException ex) {
-            return null;
-        }
-    }
-
     // Specific to RMI-IIOP
     /**
      * Java to IDL ptc-02-01-12 1.5.1
@@ -849,6 +839,22 @@
     }
 
     /**
+     * Returns true if represented class is serializable or externalizable and
+     * defines a conformant writeReplace method.  Otherwise, returns false.
+     */
+    boolean hasWriteReplaceMethod() {
+        return (writeReplaceObjectMethod != null);
+    }
+
+    /**
+     * Returns true if represented class is serializable or externalizable and
+     * defines a conformant readResolve method.  Otherwise, returns false.
+     */
+    boolean hasReadResolveMethod() {
+        return (readResolveObjectMethod != null);
+    }
+
+    /**
      * Returns when or not this class should be custom
      * marshaled (use chunking).  This should happen if
      * it is Externalizable OR if it or
@@ -904,7 +910,7 @@
     {
         if (cons != null) {
             try {
-                return cons.newInstance(new Object[0]);
+                return cons.newInstance();
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
                 InternalError ie = new InternalError();
@@ -912,7 +918,7 @@
                 throw ie ;
             }
         } else {
-            throw new UnsupportedOperationException();
+            throw new UnsupportedOperationException("no constructor for " + ofClass);
         }
     }
 
@@ -921,15 +927,8 @@
      * Access checks are disabled on the returned constructor (if any), since
      * the defining class may still be non-public.
      */
-    private static Constructor getExternalizableConstructor(Class<?> cl) {
-        try {
-            Constructor cons = cl.getDeclaredConstructor(new Class<?>[0]);
-            cons.setAccessible(true);
-            return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
-                cons : null;
-        } catch (NoSuchMethodException ex) {
-            return null;
-        }
+    private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
+        return bridge.newConstructorForExternalization(cl);
     }
 
     /**
@@ -937,28 +936,8 @@
      * superclass, or null if none found.  Access checks are disabled on the
      * returned constructor (if any).
      */
-    private static Constructor getSerializableConstructor(Class<?> cl) {
-        Class<?> initCl = cl;
-        while (Serializable.class.isAssignableFrom(initCl)) {
-            if ((initCl = initCl.getSuperclass()) == null) {
-                return null;
-            }
-        }
-        try {
-            Constructor cons = initCl.getDeclaredConstructor(new Class<?>[0]);
-            int mods = cons.getModifiers();
-            if ((mods & Modifier.PRIVATE) != 0 ||
-                ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
-                 !packageEquals(cl, initCl)))
-            {
-                return null;
-            }
-            cons = bridge.newConstructorForSerialization(cl, cons);
-            cons.setAccessible(true);
-            return cons;
-        } catch (NoSuchMethodException ex) {
-            return null;
-        }
+    private static Constructor<?> getSerializableConstructor(Class<?> cl) {
+        return bridge.newConstructorForSerialization(cl);
     }
 
     /*
@@ -1522,11 +1501,11 @@
      * @since JDK 1.2
      */
     private boolean hasExternalizableBlockData;
-    Method writeObjectMethod;
-    Method readObjectMethod;
-    private transient Method writeReplaceObjectMethod;
-    private transient Method readResolveObjectMethod;
-    private Constructor cons ;
+    private transient MethodHandle writeObjectMethod;
+    private transient MethodHandle readObjectMethod;
+    private transient MethodHandle writeReplaceObjectMethod;
+    private transient MethodHandle readResolveObjectMethod;
+    private transient Constructor<?> cons;
 
     /**
      * Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a
@@ -1543,44 +1522,12 @@
      */
     private ObjectStreamClass localClassDesc;
 
-    /* Find out if the class has a static class initializer <clinit> */
-    private static Method hasStaticInitializerMethod = null;
     /**
      * Returns true if the given class defines a static initializer method,
      * false otherwise.
      */
     private static boolean hasStaticInitializer(Class<?> cl) {
-        if (hasStaticInitializerMethod == null) {
-            Class<?> classWithThisMethod = null;
-
-            try {
-                if (classWithThisMethod == null)
-                    classWithThisMethod = java.io.ObjectStreamClass.class;
-
-                hasStaticInitializerMethod =
-                    classWithThisMethod.getDeclaredMethod("hasStaticInitializer",
-                                                          new Class<?>[] { Class.class });
-            } catch (NoSuchMethodException ex) {
-            }
-
-            if (hasStaticInitializerMethod == null) {
-                // XXX I18N, logging needed
-                throw new InternalError("Can't find hasStaticInitializer method on "
-                                        + classWithThisMethod.getName());
-            }
-            hasStaticInitializerMethod.setAccessible(true);
-        }
-
-        try {
-            Boolean retval = (Boolean)
-                hasStaticInitializerMethod.invoke(null, new Object[] { cl });
-            return retval.booleanValue();
-        } catch (Exception ex) {
-            // XXX I18N, logging needed
-            InternalError ie = new InternalError( "Error invoking hasStaticInitializer" ) ;
-            ie.initCause( ex ) ;
-            throw ie ;
-        }
+        return bridge.hasStaticInitializerForSerialization(cl);
     }
 
 
@@ -1754,7 +1701,6 @@
         if ((meth == null) || (meth.getReturnType() != returnType)) {
             return null;
         }
-        meth.setAccessible(true);
         int mods = meth.getModifiers();
         if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
             return null;
--- a/src/java.corba/share/classes/module-info.java	Thu Oct 20 18:38:08 2016 +0000
+++ b/src/java.corba/share/classes/module-info.java	Mon Oct 24 14:53:29 2016 -0400
@@ -32,6 +32,7 @@
     requires java.logging;
     requires java.naming;
     requires java.transaction;
+    requires jdk.unsupported;
 
     exports javax.activity;
     exports javax.rmi;
--- a/src/java.corba/share/classes/sun/corba/Bridge.java	Thu Oct 20 18:38:08 2016 +0000
+++ b/src/java.corba/share/classes/sun/corba/Bridge.java	Mon Oct 24 14:53:29 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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
@@ -25,25 +25,24 @@
 
 package sun.corba ;
 
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
 import java.lang.reflect.Field ;
-import java.lang.reflect.Method ;
 import java.lang.reflect.Constructor ;
-import java.lang.reflect.InvocationTargetException ;
-
-import java.io.ObjectInputStream ;
 
 import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
 
-import jdk.internal.misc.Unsafe ;
-import jdk.internal.reflect.ReflectionFactory;
+import sun.misc.Unsafe;
+import sun.reflect.ReflectionFactory;
 
 /** This class provides the methods for fundamental JVM operations
  * needed in the ORB that are not part of the public Java API.  This includes:
  * <ul>
  * <li>throwException, which can throw undeclared checked exceptions.
- * This is needed to handle throwing arbitrary exceptions across a standardized OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
+ * This is needed to handle throwing arbitrary exceptions across a standardized
+ * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
  * <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
  * This is used for setting uninitialzed non-static final fields (which is
  * impossible with reflection) and for speed.</li>
@@ -71,88 +70,28 @@
  */
 public final class Bridge
 {
-    private static final Class[] NO_ARGS = new Class[] {};
     private static final Permission getBridgePermission =
-        new BridgePermission( "getBridge" ) ;
+            new BridgePermission("getBridge");
     private static Bridge bridge = null ;
 
-    // latestUserDefinedLoader() is a private static method
-    // in ObjectInputStream in JDK 1.3 through 1.5.
-    // We use reflection in a doPrivileged block to get a
-    // Method reference and make it accessible.
-    private final Method latestUserDefinedLoaderMethod ;
-    private final Unsafe unsafe ;
+    /** Access to Unsafe to read/write fields. */
+    private static final Unsafe unsafe = AccessController.doPrivileged(
+            (PrivilegedAction<Unsafe>)() -> {
+                try {
+                    Field field = Unsafe.class.getDeclaredField("theUnsafe");
+                    field.setAccessible(true);
+                    return (Unsafe)field.get(null);
+
+                } catch (NoSuchFieldException |IllegalAccessException ex) {
+                    throw new InternalError("Unsafe.theUnsafe field not available", ex);
+                }
+            }
+    ) ;
+
     private final ReflectionFactory reflectionFactory ;
 
-    private Method getLatestUserDefinedLoaderMethod()
-    {
-        return (Method) AccessController.doPrivileged(
-            new PrivilegedAction()
-            {
-                public Object run()
-                {
-                    Method result = null;
-
-                    try {
-                        Class io = ObjectInputStream.class;
-                        result = io.getDeclaredMethod(
-                            "latestUserDefinedLoader", NO_ARGS);
-                        result.setAccessible(true);
-                    } catch (NoSuchMethodException nsme) {
-                        Error err = new Error( "java.io.ObjectInputStream" +
-                            " latestUserDefinedLoader " + nsme );
-                        err.initCause(nsme) ;
-                        throw err ;
-                    }
-
-                    return result;
-                }
-            }
-        );
-    }
-
-    private Unsafe getUnsafe() {
-        Field fld = (Field)AccessController.doPrivileged(
-            new PrivilegedAction()
-            {
-                public Object run()
-                {
-                    Field fld = null ;
-
-                    try {
-                        Class unsafeClass = jdk.internal.misc.Unsafe.class ;
-                        fld = unsafeClass.getDeclaredField( "theUnsafe" ) ;
-                        fld.setAccessible( true ) ;
-                        return fld ;
-                    } catch (NoSuchFieldException exc) {
-                        Error err = new Error( "Could not access Unsafe" ) ;
-                        err.initCause( exc ) ;
-                        throw err ;
-                    }
-                }
-            }
-        ) ;
-
-        Unsafe unsafe = null;
-
-        try {
-            unsafe = (Unsafe)(fld.get( null )) ;
-        } catch (Throwable t) {
-            Error err = new Error( "Could not access Unsafe" ) ;
-            err.initCause( t ) ;
-            throw err ;
-        }
-
-        return unsafe ;
-    }
-
-
-    private Bridge()
-    {
-        latestUserDefinedLoaderMethod = getLatestUserDefinedLoaderMethod();
-        unsafe = getUnsafe() ;
-        reflectionFactory = (ReflectionFactory)AccessController.doPrivileged(
-            new ReflectionFactory.GetReflectionFactoryAction());
+    private Bridge() {
+        reflectionFactory = ReflectionFactory.getReflectionFactory();
     }
 
     /** Fetch the Bridge singleton.  This requires the following
@@ -182,23 +121,8 @@
     /** Obtain the latest user defined ClassLoader from the call stack.
      * This is required by the RMI-IIOP specification.
      */
-    public final ClassLoader getLatestUserDefinedLoader()
-    {
-        try {
-            // Invoke the ObjectInputStream.latestUserDefinedLoader method
-            return (ClassLoader)latestUserDefinedLoaderMethod.invoke(null,
-                                                                     (Object[])NO_ARGS);
-        } catch (InvocationTargetException ite) {
-            Error err = new Error(
-                "sun.corba.Bridge.latestUserDefinedLoader: " + ite ) ;
-            err.initCause( ite ) ;
-            throw err ;
-        } catch (IllegalAccessException iae) {
-            Error err = new Error(
-                "sun.corba.Bridge.latestUserDefinedLoader: " + iae ) ;
-            err.initCause( iae ) ;
-            throw err ;
-        }
+    public final ClassLoader getLatestUserDefinedLoader() {
+        return jdk.internal.misc.VM.latestUserDefinedLoader();
     }
 
     /**
@@ -345,6 +269,23 @@
         return unsafe.objectFieldOffset( f ) ;
     }
 
+    /**
+     * Returns the offset of a static field.
+     */
+    public final long staticFieldOffset(Field f)
+    {
+        return unsafe.staticFieldOffset( f ) ;
+    }
+
+    /**
+     * Ensure that the class has been initalized.
+     * @param cl the class to ensure is initialized
+     */
+    public final void ensureClassInitialized(Class<?> cl) {
+        unsafe.ensureClassInitialized(cl);
+    }
+
+
     /** Throw the exception.
      * The exception may be an undeclared checked exception.
      */
@@ -353,16 +294,55 @@
         unsafe.throwException( ee ) ;
     }
 
-    /** Obtain a constructor for Class cl using constructor cons which
-     * may be the constructor defined in a superclass of cl.  This is
-     * used to create a constructor for Serializable classes that
-     * constructs an instance of the Serializable class using the
+    /**
+     * Obtain a constructor for Class cl.
+     * This is used to create a constructor for Serializable classes that
+     * construct an instance of the Serializable class using the
      * no args constructor of the first non-Serializable superclass
      * of the Serializable class.
      */
-    public final Constructor newConstructorForSerialization( Class cl,
-        Constructor cons )
-    {
-        return reflectionFactory.newConstructorForSerialization( cl, cons ) ;
+    public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
+        return reflectionFactory.newConstructorForSerialization( cl ) ;
     }
+
+    public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+        return reflectionFactory.newConstructorForExternalization( cl ) ;
+    }
+
+    /**
+     * Returns true if the given class defines a static initializer method,
+     * false otherwise.
+     */
+    public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+        return reflectionFactory.hasStaticInitializerForSerialization(cl);
+    }
+
+    public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+        return reflectionFactory.writeObjectForSerialization(cl);
+    }
+
+    public final MethodHandle readObjectForSerialization(Class<?> cl) {
+        return reflectionFactory.readObjectForSerialization(cl);
+    }
+
+    public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+        return reflectionFactory.readObjectNoDataForSerialization(cl);
+    }
+
+    public final MethodHandle readResolveForSerialization(Class<?> cl) {
+        return reflectionFactory.readResolveForSerialization(cl);
+    }
+
+    public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+        return reflectionFactory.writeReplaceForSerialization(cl);
+    }
+
+    /**
+     * Return a new OptionalDataException instance.
+     * @return a new OptionalDataException instance
+     */
+    public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+        return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
+    }
+
 }
--- a/src/java.corba/share/classes/sun/corba/SharedSecrets.java	Thu Oct 20 18:38:08 2016 +0000
+++ b/src/java.corba/share/classes/sun/corba/SharedSecrets.java	Mon Oct 24 14:53:29 2016 -0400
@@ -25,13 +25,13 @@
 
 package sun.corba;
 
-import com.sun.corba.se.impl.io.ValueUtility;
-import jdk.internal.misc.Unsafe;
-
 import java.lang.reflect.Field;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
+import com.sun.corba.se.impl.io.ValueUtility;
+import sun.misc.Unsafe;
+
 /** A repository of "shared secrets", which are a mechanism for
     calling implementation-private methods in another package without
     using reflection. A package-private class implements a public
@@ -43,23 +43,23 @@
 
 // SharedSecrets cloned in corba repo to avoid build issues
 public class SharedSecrets {
-    private static final Unsafe unsafe = getUnsafe();
+
+    /** Access to Unsafe to read/write fields. */
+    private static final Unsafe unsafe = AccessController.doPrivileged(
+            (PrivilegedAction<Unsafe>)() -> {
+                try {
+                    Field field = Unsafe.class.getDeclaredField("theUnsafe");
+                    field.setAccessible(true);
+                    return (Unsafe)field.get(null);
+
+                } catch (NoSuchFieldException |IllegalAccessException ex) {
+                    throw new InternalError("Unsafe.theUnsafe field not available", ex);
+                }
+            }
+    );
+
     private static JavaCorbaAccess javaCorbaAccess;
 
-     private static Unsafe getUnsafe() {
-          PrivilegedAction<Unsafe> pa = () -> {
-               Class<?> unsafeClass = jdk.internal.misc.Unsafe.class ;
-               try {
-                    Field f = unsafeClass.getDeclaredField("theUnsafe");
-                    f.setAccessible(true);
-                    return (Unsafe) f.get(null);
-               } catch (Exception e) {
-                    throw new Error(e);
-               }
-          };
-          return AccessController.doPrivileged(pa);
-     }
-
     public static JavaCorbaAccess getJavaCorbaAccess() {
         if (javaCorbaAccess == null) {
             // Ensure ValueUtility is initialized; we know that that class