8164908: ReflectionFactory support for IIOP and custom serialization
Update IIOP Streams to use ReflectionFactory and Unsafe Reviewed-by: alanb, chegar, plevart, amlu
This commit is contained in:
parent
a4cf9a8666
commit
bc7cb4bb75
@ -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 sun.corba.Bridge ;
|
||||
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 org.omg.CORBA.TypeCode;
|
||||
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 @@ public class IIOPInputStream
|
||||
|
||||
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 @@ public class IIOPInputStream
|
||||
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 @@ public class IIOPInputStream
|
||||
if (!objectRead)
|
||||
result = new EOFException("No more optional data");
|
||||
else
|
||||
result = createOptionalDataException();
|
||||
result = bridge.newOptionalDataExceptionForSerialization(true);
|
||||
|
||||
result.initCause(marshalException);
|
||||
|
||||
@ -1230,8 +1152,7 @@ public class IIOPInputStream
|
||||
|
||||
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 @@ public class IIOPInputStream
|
||||
|
||||
readObjectState.beginUnmarshalCustomValue(this,
|
||||
calledDefaultWriteObject,
|
||||
(currentClassDesc.readObjectMethod
|
||||
!= null));
|
||||
currentClassDesc.hasReadObject());
|
||||
}
|
||||
|
||||
boolean usedReadObject = false;
|
||||
@ -1714,13 +1634,8 @@ public class IIOPInputStream
|
||||
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 @@ public class IIOPInputStream
|
||||
else
|
||||
// XXX I18N, logging needed.
|
||||
throw new Error("internal error");
|
||||
} catch (IllegalAccessException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ public class IIOPOutputStream
|
||||
writeObjectState.enterWriteObject(this);
|
||||
|
||||
// writeObject(obj, c, this);
|
||||
osc.writeObjectMethod.invoke( obj, writeObjectArgList ) ;
|
||||
osc.invokeWriteObject( obj, this ) ;
|
||||
|
||||
writeObjectState.exitWriteObject(this);
|
||||
|
||||
@ -636,8 +626,6 @@ public class IIOPOutputStream
|
||||
else
|
||||
// XXX I18N, Logging needed.
|
||||
throw new Error("invokeObjectWriter internal error",e);
|
||||
} catch (IllegalAccessException e) {
|
||||
// cannot happen
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,60 +749,53 @@ public class IIOPOutputStream
|
||||
*/
|
||||
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 ) ;
|
||||
byte byteValue = bridge.getByte(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_octet(byteValue);
|
||||
break;
|
||||
case 'C':
|
||||
char charValue = fields[i].getField().getChar( o ) ;
|
||||
char charValue = bridge.getChar(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_wchar(charValue);
|
||||
break;
|
||||
case 'F':
|
||||
float floatValue = fields[i].getField().getFloat( o ) ;
|
||||
float floatValue = bridge.getFloat(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_float(floatValue);
|
||||
break;
|
||||
case 'D' :
|
||||
double doubleValue = fields[i].getField().getDouble( o ) ;
|
||||
double doubleValue = bridge.getDouble(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_double(doubleValue);
|
||||
break;
|
||||
case 'I':
|
||||
int intValue = fields[i].getField().getInt( o ) ;
|
||||
int intValue = bridge.getInt(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_long(intValue);
|
||||
break;
|
||||
case 'J':
|
||||
long longValue = fields[i].getField().getLong( o ) ;
|
||||
long longValue = bridge.getLong(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_longlong(longValue);
|
||||
break;
|
||||
case 'S':
|
||||
short shortValue = fields[i].getField().getShort( o ) ;
|
||||
short shortValue = bridge.getShort(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_short(shortValue);
|
||||
break;
|
||||
case 'Z':
|
||||
boolean booleanValue = fields[i].getField().getBoolean( o ) ;
|
||||
boolean booleanValue = bridge.getBoolean(o, fields[i].getFieldID()) ;
|
||||
orbStream.write_boolean(booleanValue);
|
||||
break;
|
||||
case '[':
|
||||
case 'L':
|
||||
Object objectValue = fields[i].getField().get( o ) ;
|
||||
Object objectValue = bridge.getObject(o, fields[i].getFieldID()) ;
|
||||
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() ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 class ObjectStreamClass implements java.io.Serializable {
|
||||
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
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);
|
||||
return (Serializable) writeReplaceObjectMethod.invoke(value);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
throw new InternalError("unexpected error", t);
|
||||
}
|
||||
}
|
||||
else return value;
|
||||
@ -325,9 +347,9 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
public Object readResolve(Object value) {
|
||||
if (readResolveObjectMethod != null) {
|
||||
try {
|
||||
return readResolveObjectMethod.invoke(value,noArgsList);
|
||||
return readResolveObjectMethod.invoke(value);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
throw new InternalError("unexpected error", t);
|
||||
}
|
||||
}
|
||||
else return value;
|
||||
@ -382,29 +404,32 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
*/
|
||||
}
|
||||
|
||||
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];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
@ -453,10 +478,8 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
int modifiers = fld.getModifiers();
|
||||
if (!Modifier.isStatic(modifiers) &&
|
||||
!Modifier.isTransient(modifiers)) {
|
||||
fld.setAccessible(true) ;
|
||||
tempFields[numFields++] = new ObjectStreamField(fld);
|
||||
}
|
||||
}
|
||||
@ -487,7 +509,6 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -848,6 +838,22 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
return writeObjectMethod != null ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -904,7 +910,7 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
{
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
throw ie ;
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("no constructor for " + ofClass);
|
||||
}
|
||||
}
|
||||
|
||||
@ -921,15 +927,8 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
* 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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
* 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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
* @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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
*/
|
||||
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 @@ public class ObjectStreamClass implements java.io.Serializable {
|
||||
if ((meth == null) || (meth.getReturnType() != returnType)) {
|
||||
return null;
|
||||
}
|
||||
meth.setAccessible(true);
|
||||
int mods = meth.getModifiers();
|
||||
if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
|
||||
return null;
|
||||
|
@ -32,6 +32,7 @@ module java.corba {
|
||||
requires java.logging;
|
||||
requires java.naming;
|
||||
requires java.transaction;
|
||||
requires jdk.unsupported;
|
||||
|
||||
exports javax.activity;
|
||||
exports javax.rmi;
|
||||
|
@ -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 @@ import jdk.internal.reflect.ReflectionFactory;
|
||||
*/
|
||||
public final class Bridge
|
||||
{
|
||||
private static final Class[] NO_ARGS = new Class[] {};
|
||||
private static final Permission getBridgePermission =
|
||||
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 @@ public final class Bridge
|
||||
/** 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 @@ public final class Bridge
|
||||
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 @@ public final class Bridge
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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,22 +43,22 @@ import java.security.PrivilegedAction;
|
||||
|
||||
// SharedSecrets cloned in corba repo to avoid build issues
|
||||
public class SharedSecrets {
|
||||
private static final Unsafe unsafe = getUnsafe();
|
||||
private static JavaCorbaAccess javaCorbaAccess;
|
||||
|
||||
private static Unsafe getUnsafe() {
|
||||
PrivilegedAction<Unsafe> pa = () -> {
|
||||
Class<?> unsafeClass = jdk.internal.misc.Unsafe.class ;
|
||||
/** Access to Unsafe to read/write fields. */
|
||||
private static final Unsafe unsafe = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Unsafe>)() -> {
|
||||
try {
|
||||
Field f = unsafeClass.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
return (Unsafe) f.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
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);
|
||||
}
|
||||
};
|
||||
return AccessController.doPrivileged(pa);
|
||||
}
|
||||
);
|
||||
|
||||
private static JavaCorbaAccess javaCorbaAccess;
|
||||
|
||||
public static JavaCorbaAccess getJavaCorbaAccess() {
|
||||
if (javaCorbaAccess == null) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user