# HG changeset patch # User Jaroslav Tulach # Date 1359393321 -3600 # Node ID 3fcc279c921bec3e1a8e746f4a5d392b8fc305e1 # Parent 3d10a6d5565398acc026f36eca2acfecf410f12d Making new clases (mostly java.io.Object*) compilable diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/beans/ChangeListenerMap.java --- a/emul/compact/src/main/java/java/beans/ChangeListenerMap.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/beans/ChangeListenerMap.java Mon Jan 28 18:15:21 2013 +0100 @@ -33,6 +33,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.apidesign.bck2brwsr.emul.lang.System; /** * This is an abstract class that provides base functionality diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/beans/VetoableChangeSupport.java --- a/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java Mon Jan 28 18:15:21 2013 +0100 @@ -31,6 +31,7 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Map.Entry; +import org.apidesign.bck2brwsr.emul.lang.System; /** * This is a utility class that can be used by beans that support constrained diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/io/ObjectInputStream.java --- a/emul/compact/src/main/java/java/io/ObjectInputStream.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/io/ObjectInputStream.java Mon Jan 28 18:15:21 2013 +0100 @@ -25,22 +25,12 @@ package java.io; -import java.io.ObjectStreamClass.WeakClassKey; -import java.lang.ref.ReferenceQueue; import java.lang.reflect.Array; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import static java.io.ObjectStreamClass.processQueue; +import org.apidesign.bck2brwsr.emul.lang.System; /** * An ObjectInputStream deserializes primitive data and objects previously @@ -226,16 +216,6 @@ primClasses.put("void", void.class); } - private static class Caches { - /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); - } - /** filter stream for handling block data conversion */ private final BlockDataInputStream bin; /** validation callback list */ @@ -265,7 +245,7 @@ * object currently being deserialized and descriptor for current class. * Null when not during readObject upcall. */ - private SerialCallbackContext curContext; + private Object curContext; /** * Creates an ObjectInputStream that reads from the specified InputStream. @@ -316,14 +296,7 @@ * @see java.io.SerializablePermission */ protected ObjectInputStream() throws IOException, SecurityException { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - bin = null; - handles = null; - vlist = null; - enableOverride = true; + throw new SecurityException(); } /** @@ -359,29 +332,7 @@ public final Object readObject() throws IOException, ClassNotFoundException { - if (enableOverride) { - return readObjectOverride(); - } - - // if nested read, passHandle contains handle of enclosing object - int outerHandle = passHandle; - try { - Object obj = readObject0(false); - handles.markDependency(outerHandle, passHandle); - ClassNotFoundException ex = handles.lookupException(passHandle); - if (ex != null) { - throw ex; - } - if (depth == 0) { - vlist.doCallbacks(); - } - return obj; - } finally { - passHandle = outerHandle; - if (closed && depth == 0) { - clear(); - } - } + throw new IOException(); } /** @@ -492,8 +443,8 @@ if (curContext == null) { throw new NotActiveException("not in call to readObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = null; // curContext.getObj(); + ObjectStreamClass curDesc = null; // curContext.getDesc(); bin.setBlockDataMode(false); defaultReadFields(curObj, curDesc); bin.setBlockDataMode(true); @@ -530,8 +481,8 @@ if (curContext == null) { throw new NotActiveException("not in call to readObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = null; // curContext.getObj(); + ObjectStreamClass curDesc = null; // curContext.getDesc(); bin.setBlockDataMode(false); GetFieldImpl getField = new GetFieldImpl(curDesc); getField.readFields(); @@ -769,17 +720,7 @@ protected boolean enableResolveObject(boolean enable) throws SecurityException { - if (enable == enableResolve) { - return enable; - } - if (enable) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBSTITUTION_PERMISSION); - } - } - enableResolve = enable; - return !enableResolve; + throw new SecurityException(); } /** @@ -1233,53 +1174,7 @@ if (cl == ObjectInputStream.class) { return; } - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return; - } - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); - Caches.subclassAudits.putIfAbsent(key, result); - } - if (result.booleanValue()) { - return; - } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - - /** - * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. - */ - private static boolean auditSubclass(final Class subcl) { - Boolean result = AccessController.doPrivileged( - new PrivilegedAction() { - public Boolean run() { - for (Class cl = subcl; - cl != ObjectInputStream.class; - cl = cl.getSuperclass()) - { - try { - cl.getDeclaredMethod( - "readUnshared", (Class[]) null); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - try { - cl.getDeclaredMethod("readFields", (Class[]) null); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - } - return Boolean.TRUE; - } - } - ); - return result.booleanValue(); + throw new SecurityException(); } /** @@ -1798,7 +1693,7 @@ private void readExternalData(Externalizable obj, ObjectStreamClass desc) throws IOException { - SerialCallbackContext oldContext = curContext; + Object oldContext = curContext; curContext = null; try { boolean blocked = desc.hasBlockExternalData(); @@ -1857,10 +1752,10 @@ slotDesc.hasReadObjectMethod() && handles.lookupException(passHandle) == null) { - SerialCallbackContext oldContext = curContext; + Object oldContext = curContext; try { - curContext = new SerialCallbackContext(obj, slotDesc); + curContext = null; //new SerialCallbackContext(obj, slotDesc); bin.setBlockDataMode(true); slotDesc.invokeReadObject(obj, this); @@ -1874,7 +1769,7 @@ */ handles.markException(passHandle, ex); } finally { - curContext.setUsed(); + //curContext.setUsed(); curContext = oldContext; } @@ -2158,24 +2053,6 @@ */ private static class ValidationList { - private static class Callback { - final ObjectInputValidation obj; - final int priority; - Callback next; - final AccessControlContext acc; - - Callback(ObjectInputValidation obj, int priority, Callback next, - AccessControlContext acc) - { - this.obj = obj; - this.priority = priority; - this.next = next; - this.acc = acc; - } - } - - /** linked list of callbacks */ - private Callback list; /** * Creates new (empty) ValidationList. @@ -2193,18 +2070,7 @@ if (obj == null) { throw new InvalidObjectException("null callback"); } - - Callback prev = null, cur = list; - while (cur != null && priority < cur.priority) { - prev = cur; - cur = cur.next; - } - AccessControlContext acc = AccessController.getContext(); - if (prev != null) { - prev.next = new Callback(obj, priority, cur, acc); - } else { - list = new Callback(obj, priority, list, acc); - } + throw new InvalidObjectException("Does not work."); } /** @@ -2215,29 +2081,12 @@ * and the exception propagated upwards. */ void doCallbacks() throws InvalidObjectException { - try { - while (list != null) { - AccessController.doPrivileged( - new PrivilegedExceptionAction() - { - public Void run() throws InvalidObjectException { - list.obj.validateObject(); - return null; - } - }, list.acc); - list = list.next; - } - } catch (PrivilegedActionException ex) { - list = null; - throw (InvalidObjectException) ex.getException(); - } } /** * Resets the callback list to its initial (empty) state. */ public void clear() { - list = null; } } diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/io/ObjectOutputStream.java --- a/emul/compact/src/main/java/java/io/ObjectOutputStream.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/io/ObjectOutputStream.java Mon Jan 28 18:15:21 2013 +0100 @@ -25,17 +25,10 @@ package java.io; -import java.io.ObjectStreamClass.WeakClassKey; -import java.lang.ref.ReferenceQueue; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import static java.io.ObjectStreamClass.processQueue; -import java.io.SerialCallbackContext; +import org.apidesign.bck2brwsr.emul.lang.System; /** * An ObjectOutputStream writes primitive data types and graphs of Java objects @@ -161,17 +154,6 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants { - - private static class Caches { - /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); - } - /** filter stream for handling block data conversion */ private final BlockDataOutputStream bout; /** obj -> wire handle map */ @@ -197,7 +179,7 @@ * object currently being serialized and descriptor for current class. * Null when not during writeObject upcall. */ - private SerialCallbackContext curContext; + private Object curContext; /** current PutField object */ private PutFieldImpl curPut; @@ -208,10 +190,7 @@ * value of "sun.io.serialization.extendedDebugInfo" property, * as true or false for extended information about exception's place */ - private static final boolean extendedDebugInfo = - java.security.AccessController.doPrivileged( - new sun.security.action.GetBooleanAction( - "sun.io.serialization.extendedDebugInfo")).booleanValue(); + private static final boolean extendedDebugInfo = false; /** * Creates an ObjectOutputStream that writes to the specified OutputStream. @@ -268,15 +247,7 @@ * @see java.io.SerializablePermission */ protected ObjectOutputStream() throws IOException, SecurityException { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - bout = null; - handles = null; - subs = null; - enableOverride = true; - debugInfoStack = null; + throw new SecurityException(); } /** @@ -432,8 +403,8 @@ if ( curContext == null ) { throw new NotActiveException("not in call to writeObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = null; // curContext.getObj(); + ObjectStreamClass curDesc = null; // curContext.getDesc(); bout.setBlockDataMode(false); defaultWriteFields(curObj, curDesc); bout.setBlockDataMode(true); @@ -454,8 +425,8 @@ if (curContext == null) { throw new NotActiveException("not in call to writeObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = null; // curContext.getObj(); + ObjectStreamClass curDesc = null; // curContext.getDesc(); curPut = new PutFieldImpl(curDesc); } return curPut; @@ -607,17 +578,7 @@ protected boolean enableReplaceObject(boolean enable) throws SecurityException { - if (enable == enableReplace) { - return enable; - } - if (enable) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBSTITUTION_PERMISSION); - } - } - enableReplace = enable; - return !enableReplace; + throw new SecurityException(); } /** @@ -1038,53 +999,7 @@ if (cl == ObjectOutputStream.class) { return; } - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return; - } - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); - Caches.subclassAudits.putIfAbsent(key, result); - } - if (result.booleanValue()) { - return; - } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - - /** - * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. - */ - private static boolean auditSubclass(final Class subcl) { - Boolean result = AccessController.doPrivileged( - new PrivilegedAction() { - public Boolean run() { - for (Class cl = subcl; - cl != ObjectOutputStream.class; - cl = cl.getSuperclass()) - { - try { - cl.getDeclaredMethod( - "writeUnshared", new Class[] { Object.class }); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - try { - cl.getDeclaredMethod("putFields", (Class[]) null); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - } - return Boolean.TRUE; - } - } - ); - return result.booleanValue(); + throw new SecurityException(); } /** @@ -1433,7 +1348,7 @@ if (extendedDebugInfo) { debugInfoStack.push("writeExternal data"); } - SerialCallbackContext oldContext = curContext; + Object oldContext = curContext; try { curContext = null; if (protocol == PROTOCOL_VERSION_1) { @@ -1467,7 +1382,7 @@ if (slotDesc.hasWriteObjectMethod()) { PutFieldImpl oldPut = curPut; curPut = null; - SerialCallbackContext oldContext = curContext; + Object oldContext = curContext; if (extendedDebugInfo) { debugInfoStack.push( @@ -1475,13 +1390,13 @@ slotDesc.getName() + "\")"); } try { - curContext = new SerialCallbackContext(obj, slotDesc); + curContext = new Object(); //new SerialCallbackContext(obj, slotDesc); bout.setBlockDataMode(true); slotDesc.invokeWriteObject(obj, this); bout.setBlockDataMode(false); bout.writeByte(TC_ENDBLOCKDATA); } finally { - curContext.setUsed(); + //curContext.setUsed(); curContext = oldContext; if (extendedDebugInfo) { debugInfoStack.pop(); diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/io/ObjectStreamClass.java --- a/emul/compact/src/main/java/java/io/ObjectStreamClass.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/io/ObjectStreamClass.java Mon Jan 28 18:15:21 2013 +0100 @@ -36,20 +36,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; -import java.security.AccessController; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import sun.misc.Unsafe; -import sun.reflect.ReflectionFactory; /** * Serialization's descriptor for classes. It contains the name and @@ -76,27 +68,6 @@ private static final ObjectStreamField[] serialPersistentFields = NO_FIELDS; - /** reflection factory for obtaining serialization constructors */ - private static final ReflectionFactory reflFactory = - AccessController.doPrivileged( - new ReflectionFactory.GetReflectionFactoryAction()); - - private static class Caches { - /** cache mapping local classes -> descriptors */ - static final ConcurrentMap> localDescs = - new ConcurrentHashMap<>(); - - /** cache mapping field group/local desc pairs -> field reflectors */ - static final ConcurrentMap> reflectors = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to local classes */ - private static final ReferenceQueue> localDescsQueue = - new ReferenceQueue<>(); - /** queue for WeakReferences to field reflectors keys */ - private static final ReferenceQueue> reflectorsQueue = - new ReferenceQueue<>(); - } /** class associated with this descriptor (if any) */ private Class cl; @@ -139,7 +110,7 @@ /** number of non-primitive fields */ private int numObjFields; /** reflector for setting/getting serializable field values */ - private FieldReflector fieldRefl; +// private FieldReflector fieldRefl; /** data layout of serialized objects described by this class desc */ private volatile ClassDataSlot[] dataLayout; @@ -216,13 +187,7 @@ public long getSerialVersionUID() { // REMIND: synchronize instead of relying on volatile? if (suid == null) { - suid = AccessController.doPrivileged( - new PrivilegedAction() { - public Long run() { - return computeDefaultSUID(cl); - } - } - ); + return computeDefaultSUID(cl); } return suid.longValue(); } @@ -280,26 +245,11 @@ if (!(all || Serializable.class.isAssignableFrom(cl))) { return null; } - processQueue(Caches.localDescsQueue, Caches.localDescs); - WeakClassKey key = new WeakClassKey(cl, Caches.localDescsQueue); - Reference ref = Caches.localDescs.get(key); Object entry = null; - if (ref != null) { - entry = ref.get(); - } EntryFuture future = null; if (entry == null) { EntryFuture newEntry = new EntryFuture(); Reference newRef = new SoftReference<>(newEntry); - do { - if (ref != null) { - Caches.localDescs.remove(key, ref); - } - ref = Caches.localDescs.putIfAbsent(key, newRef); - if (ref != null) { - entry = ref.get(); - } - } while (ref != null && entry == null); if (entry == null) { future = newEntry; } @@ -310,7 +260,7 @@ } if (entry instanceof EntryFuture) { future = (EntryFuture) entry; - if (future.getOwner() == Thread.currentThread()) { + if (true) { /* * Handle nested call situation described by 4803747: waiting * for future value to be set by a lookup() call further up the @@ -328,12 +278,8 @@ } catch (Throwable th) { entry = th; } - if (future.set(entry)) { - Caches.localDescs.put(key, new SoftReference(entry)); - } else { - // nested lookup call already set future - entry = future.get(); - } + // nested lookup call already set future + entry = future.get(); } if (entry instanceof ObjectStreamClass) { @@ -358,7 +304,6 @@ private static class EntryFuture { private static final Object unset = new Object(); - private final Thread owner = Thread.currentThread(); private Object entry = unset; /** @@ -390,25 +335,8 @@ interrupted = true; } } - if (interrupted) { - AccessController.doPrivileged( - new PrivilegedAction() { - public Void run() { - Thread.currentThread().interrupt(); - return null; - } - } - ); - } return entry; } - - /** - * Returns the thread that created this EntryFuture. - */ - Thread getOwner() { - return owner; - } } /** @@ -426,60 +354,9 @@ superDesc = (superCl != null) ? lookup(superCl, false) : null; localDesc = this; - if (serializable) { - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - if (isEnum) { - suid = Long.valueOf(0); - fields = NO_FIELDS; - return null; - } - if (cl.isArray()) { - fields = NO_FIELDS; - return null; - } + suid = Long.valueOf(0); + fields = NO_FIELDS; - suid = getDeclaredSUID(cl); - try { - fields = getSerialFields(cl); - computeFieldOffsets(); - } catch (InvalidClassException e) { - serializeEx = deserializeEx = e; - fields = NO_FIELDS; - } - - if (externalizable) { - cons = getExternalizableConstructor(cl); - } else { - cons = getSerializableConstructor(cl); - writeObjectMethod = getPrivateMethod(cl, "writeObject", - new Class[] { ObjectOutputStream.class }, - Void.TYPE); - readObjectMethod = getPrivateMethod(cl, "readObject", - new Class[] { ObjectInputStream.class }, - Void.TYPE); - readObjectNoDataMethod = getPrivateMethod( - cl, "readObjectNoData", null, Void.TYPE); - hasWriteObjectData = (writeObjectMethod != null); - } - writeReplaceMethod = getInheritableMethod( - cl, "writeReplace", null, Object.class); - readResolveMethod = getInheritableMethod( - cl, "readResolve", null, Object.class); - return null; - } - }); - } else { - suid = Long.valueOf(0); - fields = NO_FIELDS; - } - - try { - fieldRefl = getReflector(fields, this); - } catch (InvalidClassException ex) { - // field mismatches impossible when matching local fields vs. self - throw new InternalError(); - } if (deserializeEx == null) { if (isEnum) { @@ -533,7 +410,6 @@ readResolveMethod = localDesc.readResolveMethod; deserializeEx = localDesc.deserializeEx; } - fieldRefl = getReflector(fields, localDesc); } /** @@ -616,9 +492,8 @@ deserializeEx = localDesc.deserializeEx; } } - fieldRefl = getReflector(fields, localDesc); // reassign to matched fields so as to reflect local unshared settings - fields = fieldRefl.getFields(); + fields = null; } /** @@ -1197,7 +1072,6 @@ * non-null. */ void getPrimFieldValues(Object obj, byte[] buf) { - fieldRefl.getPrimFieldValues(obj, buf); } /** @@ -1207,7 +1081,6 @@ * non-null. */ void setPrimFieldValues(Object obj, byte[] buf) { - fieldRefl.setPrimFieldValues(obj, buf); } /** @@ -1216,7 +1089,6 @@ * the caller to ensure that obj is of the proper type if non-null. */ void getObjFieldValues(Object obj, Object[] vals) { - fieldRefl.getObjFieldValues(obj, vals); } /** @@ -1225,7 +1097,6 @@ * to ensure that obj is of the proper type if non-null. */ void setObjFieldValues(Object obj, Object[] vals) { - fieldRefl.setObjFieldValues(obj, vals); } /** @@ -1309,14 +1180,7 @@ * the defining class may still be non-public. */ private static Constructor getExternalizableConstructor(Class cl) { - try { - Constructor cons = cl.getDeclaredConstructor((Class[]) null); - cons.setAccessible(true); - return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ? - cons : null; - } catch (NoSuchMethodException ex) { - return null; - } + throw new SecurityException(); } /** @@ -1331,21 +1195,7 @@ return null; } } - try { - Constructor cons = initCl.getDeclaredConstructor((Class[]) null); - int mods = cons.getModifiers(); - if ((mods & Modifier.PRIVATE) != 0 || - ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && - !packageEquals(cl, initCl))) - { - return null; - } - cons = reflFactory.newConstructorForSerialization(cl, cons); - cons.setAccessible(true); - return cons; - } catch (NoSuchMethodException ex) { - return null; - } + throw new SecurityException(); } /** @@ -1358,31 +1208,7 @@ Class[] argTypes, Class returnType) { - Method meth = null; - Class defCl = cl; - while (defCl != null) { - try { - meth = defCl.getDeclaredMethod(name, argTypes); - break; - } catch (NoSuchMethodException ex) { - defCl = defCl.getSuperclass(); - } - } - - if ((meth == null) || (meth.getReturnType() != returnType)) { - return null; - } - meth.setAccessible(true); - int mods = meth.getModifiers(); - if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) { - return null; - } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) { - return meth; - } else if ((mods & Modifier.PRIVATE) != 0) { - return (cl == defCl) ? meth : null; - } else { - return packageEquals(cl, defCl) ? meth : null; - } + throw new SecurityException(); } /** @@ -1394,16 +1220,7 @@ 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; - } + throw new SecurityException(); } /** @@ -1548,52 +1365,7 @@ private static ObjectStreamField[] getDeclaredSerialFields(Class cl) throws InvalidClassException { - ObjectStreamField[] serialPersistentFields = null; - try { - Field f = cl.getDeclaredField("serialPersistentFields"); - int mask = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; - if ((f.getModifiers() & mask) == mask) { - f.setAccessible(true); - serialPersistentFields = (ObjectStreamField[]) f.get(null); - } - } catch (Exception ex) { - } - if (serialPersistentFields == null) { - return null; - } else if (serialPersistentFields.length == 0) { - return NO_FIELDS; - } - - ObjectStreamField[] boundFields = - new ObjectStreamField[serialPersistentFields.length]; - Set fieldNames = new HashSet<>(serialPersistentFields.length); - - for (int i = 0; i < serialPersistentFields.length; i++) { - ObjectStreamField spf = serialPersistentFields[i]; - - String fname = spf.getName(); - if (fieldNames.contains(fname)) { - throw new InvalidClassException( - "multiple serializable fields named " + fname); - } - fieldNames.add(fname); - - try { - Field f = cl.getDeclaredField(fname); - if ((f.getType() == spf.getType()) && - ((f.getModifiers() & Modifier.STATIC) == 0)) - { - boundFields[i] = - new ObjectStreamField(f, spf.isUnshared(), true); - } - } catch (NoSuchFieldException ex) { - } - if (boundFields[i] == null) { - boundFields[i] = new ObjectStreamField( - fname, spf.getType(), spf.isUnshared()); - } - } - return boundFields; + throw new SecurityException(); } /** @@ -1603,18 +1375,7 @@ * serializable fields exist, NO_FIELDS is returned. */ private static ObjectStreamField[] getDefaultSerialFields(Class cl) { - Field[] clFields = cl.getDeclaredFields(); - ArrayList list = new ArrayList<>(); - int mask = Modifier.STATIC | Modifier.TRANSIENT; - - for (int i = 0; i < clFields.length; i++) { - if ((clFields[i].getModifiers() & mask) == 0) { - list.add(new ObjectStreamField(clFields[i], false, true)); - } - } - int size = list.size(); - return (size == 0) ? NO_FIELDS : - list.toArray(new ObjectStreamField[size]); + throw new SecurityException(); } /** @@ -1622,15 +1383,6 @@ * null if none. */ private static Long getDeclaredSUID(Class cl) { - try { - Field f = cl.getDeclaredField("serialVersionUID"); - int mask = Modifier.STATIC | Modifier.FINAL; - if ((f.getModifiers() & mask) == mask) { - f.setAccessible(true); - return Long.valueOf(f.getLong(null)); - } - } catch (Exception ex) { - } return null; } @@ -1638,667 +1390,7 @@ * Computes the default serial version UID value for the given class. */ private static long computeDefaultSUID(Class cl) { - if (!Serializable.class.isAssignableFrom(cl) || Proxy.isProxyClass(cl)) - { - return 0L; - } - - try { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - DataOutputStream dout = new DataOutputStream(bout); - - dout.writeUTF(cl.getName()); - - int classMods = cl.getModifiers() & - (Modifier.PUBLIC | Modifier.FINAL | - Modifier.INTERFACE | Modifier.ABSTRACT); - - /* - * compensate for javac bug in which ABSTRACT bit was set for an - * interface only if the interface declared methods - */ - Method[] methods = cl.getDeclaredMethods(); - if ((classMods & Modifier.INTERFACE) != 0) { - classMods = (methods.length > 0) ? - (classMods | Modifier.ABSTRACT) : - (classMods & ~Modifier.ABSTRACT); - } - dout.writeInt(classMods); - - if (!cl.isArray()) { - /* - * compensate for change in 1.2FCS in which - * Class.getInterfaces() was modified to return Cloneable and - * Serializable for array classes. - */ - Class[] interfaces = cl.getInterfaces(); - String[] ifaceNames = new String[interfaces.length]; - for (int i = 0; i < interfaces.length; i++) { - ifaceNames[i] = interfaces[i].getName(); - } - Arrays.sort(ifaceNames); - for (int i = 0; i < ifaceNames.length; i++) { - dout.writeUTF(ifaceNames[i]); - } - } - - Field[] fields = cl.getDeclaredFields(); - MemberSignature[] fieldSigs = new MemberSignature[fields.length]; - for (int i = 0; i < fields.length; i++) { - fieldSigs[i] = new MemberSignature(fields[i]); - } - Arrays.sort(fieldSigs, new Comparator() { - public int compare(MemberSignature ms1, MemberSignature ms2) { - return ms1.name.compareTo(ms2.name); - } - }); - for (int i = 0; i < fieldSigs.length; i++) { - MemberSignature sig = fieldSigs[i]; - int mods = sig.member.getModifiers() & - (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED | - Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE | - Modifier.TRANSIENT); - if (((mods & Modifier.PRIVATE) == 0) || - ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0)) - { - dout.writeUTF(sig.name); - dout.writeInt(mods); - dout.writeUTF(sig.signature); - } - } - - if (hasStaticInitializer(cl)) { - dout.writeUTF(""); - dout.writeInt(Modifier.STATIC); - dout.writeUTF("()V"); - } - - Constructor[] cons = cl.getDeclaredConstructors(); - MemberSignature[] consSigs = new MemberSignature[cons.length]; - for (int i = 0; i < cons.length; i++) { - consSigs[i] = new MemberSignature(cons[i]); - } - Arrays.sort(consSigs, new Comparator() { - public int compare(MemberSignature ms1, MemberSignature ms2) { - return ms1.signature.compareTo(ms2.signature); - } - }); - for (int i = 0; i < consSigs.length; i++) { - MemberSignature sig = consSigs[i]; - int mods = sig.member.getModifiers() & - (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED | - Modifier.STATIC | Modifier.FINAL | - Modifier.SYNCHRONIZED | Modifier.NATIVE | - Modifier.ABSTRACT | Modifier.STRICT); - if ((mods & Modifier.PRIVATE) == 0) { - dout.writeUTF(""); - dout.writeInt(mods); - dout.writeUTF(sig.signature.replace('/', '.')); - } - } - - MemberSignature[] methSigs = new MemberSignature[methods.length]; - for (int i = 0; i < methods.length; i++) { - methSigs[i] = new MemberSignature(methods[i]); - } - Arrays.sort(methSigs, new Comparator() { - public int compare(MemberSignature ms1, MemberSignature ms2) { - int comp = ms1.name.compareTo(ms2.name); - if (comp == 0) { - comp = ms1.signature.compareTo(ms2.signature); - } - return comp; - } - }); - for (int i = 0; i < methSigs.length; i++) { - MemberSignature sig = methSigs[i]; - int mods = sig.member.getModifiers() & - (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED | - Modifier.STATIC | Modifier.FINAL | - Modifier.SYNCHRONIZED | Modifier.NATIVE | - Modifier.ABSTRACT | Modifier.STRICT); - if ((mods & Modifier.PRIVATE) == 0) { - dout.writeUTF(sig.name); - dout.writeInt(mods); - dout.writeUTF(sig.signature.replace('/', '.')); - } - } - - dout.flush(); - - MessageDigest md = MessageDigest.getInstance("SHA"); - byte[] hashBytes = md.digest(bout.toByteArray()); - long hash = 0; - for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { - hash = (hash << 8) | (hashBytes[i] & 0xFF); - } - return hash; - } catch (IOException ex) { - throw new InternalError(); - } catch (NoSuchAlgorithmException ex) { - throw new SecurityException(ex.getMessage()); - } + throw new SecurityException(); } - /** - * Returns true if the given class defines a static initializer method, - * false otherwise. - */ - private native static boolean hasStaticInitializer(Class cl); - - /** - * Class for computing and caching field/constructor/method signatures - * during serialVersionUID calculation. - */ - private static class MemberSignature { - - public final Member member; - public final String name; - public final String signature; - - public MemberSignature(Field field) { - member = field; - name = field.getName(); - signature = getClassSignature(field.getType()); - } - - public MemberSignature(Constructor cons) { - member = cons; - name = cons.getName(); - signature = getMethodSignature( - cons.getParameterTypes(), Void.TYPE); - } - - public MemberSignature(Method meth) { - member = meth; - name = meth.getName(); - signature = getMethodSignature( - meth.getParameterTypes(), meth.getReturnType()); - } - } - - /** - * Class for setting and retrieving serializable field values in batch. - */ - // REMIND: dynamically generate these? - private static class FieldReflector { - - /** handle for performing unsafe operations */ - private static final Unsafe unsafe = Unsafe.getUnsafe(); - - /** fields to operate on */ - private final ObjectStreamField[] fields; - /** number of primitive fields */ - private final int numPrimFields; - /** unsafe field keys for reading fields - may contain dupes */ - private final long[] readKeys; - /** unsafe fields keys for writing fields - no dupes */ - private final long[] writeKeys; - /** field data offsets */ - private final int[] offsets; - /** field type codes */ - private final char[] typeCodes; - /** field types */ - private final Class[] types; - - /** - * Constructs FieldReflector capable of setting/getting values from the - * subset of fields whose ObjectStreamFields contain non-null - * reflective Field objects. ObjectStreamFields with null Fields are - * treated as filler, for which get operations return default values - * and set operations discard given values. - */ - FieldReflector(ObjectStreamField[] fields) { - this.fields = fields; - int nfields = fields.length; - readKeys = new long[nfields]; - writeKeys = new long[nfields]; - offsets = new int[nfields]; - typeCodes = new char[nfields]; - ArrayList> typeList = new ArrayList<>(); - Set usedKeys = new HashSet<>(); - - - for (int i = 0; i < nfields; i++) { - ObjectStreamField f = fields[i]; - Field rf = f.getField(); - long key = (rf != null) ? - unsafe.objectFieldOffset(rf) : Unsafe.INVALID_FIELD_OFFSET; - readKeys[i] = key; - writeKeys[i] = usedKeys.add(key) ? - key : Unsafe.INVALID_FIELD_OFFSET; - offsets[i] = f.getOffset(); - typeCodes[i] = f.getTypeCode(); - if (!f.isPrimitive()) { - typeList.add((rf != null) ? rf.getType() : null); - } - } - - types = typeList.toArray(new Class[typeList.size()]); - numPrimFields = nfields - types.length; - } - - /** - * Returns list of ObjectStreamFields representing fields operated on - * by this reflector. The shared/unshared values and Field objects - * contained by ObjectStreamFields in the list reflect their bindings - * to locally defined serializable fields. - */ - ObjectStreamField[] getFields() { - return fields; - } - - /** - * Fetches the serializable primitive field values of object obj and - * marshals them into byte array buf starting at offset 0. The caller - * is responsible for ensuring that obj is of the proper type. - */ - void getPrimFieldValues(Object obj, byte[] buf) { - if (obj == null) { - throw new NullPointerException(); - } - /* assuming checkDefaultSerialize() has been called on the class - * descriptor this FieldReflector was obtained from, no field keys - * in array should be equal to Unsafe.INVALID_FIELD_OFFSET. - */ - for (int i = 0; i < numPrimFields; i++) { - long key = readKeys[i]; - int off = offsets[i]; - switch (typeCodes[i]) { - case 'Z': - Bits.putBoolean(buf, off, unsafe.getBoolean(obj, key)); - break; - - case 'B': - buf[off] = unsafe.getByte(obj, key); - break; - - case 'C': - Bits.putChar(buf, off, unsafe.getChar(obj, key)); - break; - - case 'S': - Bits.putShort(buf, off, unsafe.getShort(obj, key)); - break; - - case 'I': - Bits.putInt(buf, off, unsafe.getInt(obj, key)); - break; - - case 'F': - Bits.putFloat(buf, off, unsafe.getFloat(obj, key)); - break; - - case 'J': - Bits.putLong(buf, off, unsafe.getLong(obj, key)); - break; - - case 'D': - Bits.putDouble(buf, off, unsafe.getDouble(obj, key)); - break; - - default: - throw new InternalError(); - } - } - } - - /** - * Sets the serializable primitive fields of object obj using values - * unmarshalled from byte array buf starting at offset 0. The caller - * is responsible for ensuring that obj is of the proper type. - */ - void setPrimFieldValues(Object obj, byte[] buf) { - if (obj == null) { - throw new NullPointerException(); - } - for (int i = 0; i < numPrimFields; i++) { - long key = writeKeys[i]; - if (key == Unsafe.INVALID_FIELD_OFFSET) { - continue; // discard value - } - int off = offsets[i]; - switch (typeCodes[i]) { - case 'Z': - unsafe.putBoolean(obj, key, Bits.getBoolean(buf, off)); - break; - - case 'B': - unsafe.putByte(obj, key, buf[off]); - break; - - case 'C': - unsafe.putChar(obj, key, Bits.getChar(buf, off)); - break; - - case 'S': - unsafe.putShort(obj, key, Bits.getShort(buf, off)); - break; - - case 'I': - unsafe.putInt(obj, key, Bits.getInt(buf, off)); - break; - - case 'F': - unsafe.putFloat(obj, key, Bits.getFloat(buf, off)); - break; - - case 'J': - unsafe.putLong(obj, key, Bits.getLong(buf, off)); - break; - - case 'D': - unsafe.putDouble(obj, key, Bits.getDouble(buf, off)); - break; - - default: - throw new InternalError(); - } - } - } - - /** - * Fetches the serializable object field values of object obj and - * stores them in array vals starting at offset 0. The caller is - * responsible for ensuring that obj is of the proper type. - */ - void getObjFieldValues(Object obj, Object[] vals) { - if (obj == null) { - throw new NullPointerException(); - } - /* assuming checkDefaultSerialize() has been called on the class - * descriptor this FieldReflector was obtained from, no field keys - * in array should be equal to Unsafe.INVALID_FIELD_OFFSET. - */ - for (int i = numPrimFields; i < fields.length; i++) { - switch (typeCodes[i]) { - case 'L': - case '[': - vals[offsets[i]] = unsafe.getObject(obj, readKeys[i]); - break; - - default: - throw new InternalError(); - } - } - } - - /** - * Sets the serializable object fields of object obj using values from - * array vals starting at offset 0. The caller is responsible for - * ensuring that obj is of the proper type; however, attempts to set a - * field with a value of the wrong type will trigger an appropriate - * ClassCastException. - */ - void setObjFieldValues(Object obj, Object[] vals) { - if (obj == null) { - throw new NullPointerException(); - } - for (int i = numPrimFields; i < fields.length; i++) { - long key = writeKeys[i]; - if (key == Unsafe.INVALID_FIELD_OFFSET) { - continue; // discard value - } - switch (typeCodes[i]) { - case 'L': - case '[': - Object val = vals[offsets[i]]; - if (val != null && - !types[i - numPrimFields].isInstance(val)) - { - Field f = fields[i].getField(); - throw new ClassCastException( - "cannot assign instance of " + - val.getClass().getName() + " to field " + - f.getDeclaringClass().getName() + "." + - f.getName() + " of type " + - f.getType().getName() + " in instance of " + - obj.getClass().getName()); - } - unsafe.putObject(obj, key, val); - break; - - default: - throw new InternalError(); - } - } - } - } - - /** - * Matches given set of serializable fields with serializable fields - * described by the given local class descriptor, and returns a - * FieldReflector instance capable of setting/getting values from the - * subset of fields that match (non-matching fields are treated as filler, - * for which get operations return default values and set operations - * discard given values). Throws InvalidClassException if unresolvable - * type conflicts exist between the two sets of fields. - */ - private static FieldReflector getReflector(ObjectStreamField[] fields, - ObjectStreamClass localDesc) - throws InvalidClassException - { - // class irrelevant if no fields - Class cl = (localDesc != null && fields.length > 0) ? - localDesc.cl : null; - processQueue(Caches.reflectorsQueue, Caches.reflectors); - FieldReflectorKey key = new FieldReflectorKey(cl, fields, - Caches.reflectorsQueue); - Reference ref = Caches.reflectors.get(key); - Object entry = null; - if (ref != null) { - entry = ref.get(); - } - EntryFuture future = null; - if (entry == null) { - EntryFuture newEntry = new EntryFuture(); - Reference newRef = new SoftReference<>(newEntry); - do { - if (ref != null) { - Caches.reflectors.remove(key, ref); - } - ref = Caches.reflectors.putIfAbsent(key, newRef); - if (ref != null) { - entry = ref.get(); - } - } while (ref != null && entry == null); - if (entry == null) { - future = newEntry; - } - } - - if (entry instanceof FieldReflector) { // check common case first - return (FieldReflector) entry; - } else if (entry instanceof EntryFuture) { - entry = ((EntryFuture) entry).get(); - } else if (entry == null) { - try { - entry = new FieldReflector(matchFields(fields, localDesc)); - } catch (Throwable th) { - entry = th; - } - future.set(entry); - Caches.reflectors.put(key, new SoftReference(entry)); - } - - if (entry instanceof FieldReflector) { - return (FieldReflector) entry; - } else if (entry instanceof InvalidClassException) { - throw (InvalidClassException) entry; - } else if (entry instanceof RuntimeException) { - throw (RuntimeException) entry; - } else if (entry instanceof Error) { - throw (Error) entry; - } else { - throw new InternalError("unexpected entry: " + entry); - } - } - - /** - * FieldReflector cache lookup key. Keys are considered equal if they - * refer to the same class and equivalent field formats. - */ - private static class FieldReflectorKey extends WeakReference> { - - private final String sigs; - private final int hash; - private final boolean nullClass; - - FieldReflectorKey(Class cl, ObjectStreamField[] fields, - ReferenceQueue> queue) - { - super(cl, queue); - nullClass = (cl == null); - StringBuilder sbuf = new StringBuilder(); - for (int i = 0; i < fields.length; i++) { - ObjectStreamField f = fields[i]; - sbuf.append(f.getName()).append(f.getSignature()); - } - sigs = sbuf.toString(); - hash = System.identityHashCode(cl) + sigs.hashCode(); - } - - public int hashCode() { - return hash; - } - - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof FieldReflectorKey) { - FieldReflectorKey other = (FieldReflectorKey) obj; - Class referent; - return (nullClass ? other.nullClass - : ((referent = get()) != null) && - (referent == other.get())) && - sigs.equals(other.sigs); - } else { - return false; - } - } - } - - /** - * Matches given set of serializable fields with serializable fields - * obtained from the given local class descriptor (which contain bindings - * to reflective Field objects). Returns list of ObjectStreamFields in - * which each ObjectStreamField whose signature matches that of a local - * field contains a Field object for that field; unmatched - * ObjectStreamFields contain null Field objects. Shared/unshared settings - * of the returned ObjectStreamFields also reflect those of matched local - * ObjectStreamFields. Throws InvalidClassException if unresolvable type - * conflicts exist between the two sets of fields. - */ - private static ObjectStreamField[] matchFields(ObjectStreamField[] fields, - ObjectStreamClass localDesc) - throws InvalidClassException - { - ObjectStreamField[] localFields = (localDesc != null) ? - localDesc.fields : NO_FIELDS; - - /* - * Even if fields == localFields, we cannot simply return localFields - * here. In previous implementations of serialization, - * ObjectStreamField.getType() returned Object.class if the - * ObjectStreamField represented a non-primitive field and belonged to - * a non-local class descriptor. To preserve this (questionable) - * behavior, the ObjectStreamField instances returned by matchFields - * cannot report non-primitive types other than Object.class; hence - * localFields cannot be returned directly. - */ - - ObjectStreamField[] matches = new ObjectStreamField[fields.length]; - for (int i = 0; i < fields.length; i++) { - ObjectStreamField f = fields[i], m = null; - for (int j = 0; j < localFields.length; j++) { - ObjectStreamField lf = localFields[j]; - if (f.getName().equals(lf.getName())) { - if ((f.isPrimitive() || lf.isPrimitive()) && - f.getTypeCode() != lf.getTypeCode()) - { - throw new InvalidClassException(localDesc.name, - "incompatible types for field " + f.getName()); - } - if (lf.getField() != null) { - m = new ObjectStreamField( - lf.getField(), lf.isUnshared(), false); - } else { - m = new ObjectStreamField( - lf.getName(), lf.getSignature(), lf.isUnshared()); - } - } - } - if (m == null) { - m = new ObjectStreamField( - f.getName(), f.getSignature(), false); - } - m.setOffset(f.getOffset()); - matches[i] = m; - } - return matches; - } - - /** - * Removes from the specified map any keys that have been enqueued - * on the specified reference queue. - */ - static void processQueue(ReferenceQueue> queue, - ConcurrentMap>, ?> map) - { - Reference> ref; - while((ref = queue.poll()) != null) { - map.remove(ref); - } - } - - /** - * Weak key for Class objects. - * - **/ - static class WeakClassKey extends WeakReference> { - /** - * saved value of the referent's identity hash code, to maintain - * a consistent hash code after the referent has been cleared - */ - private final int hash; - - /** - * Create a new WeakClassKey to the given object, registered - * with a queue. - */ - WeakClassKey(Class cl, ReferenceQueue> refQueue) { - super(cl, refQueue); - hash = System.identityHashCode(cl); - } - - /** - * Returns the identity hash code of the original referent. - */ - public int hashCode() { - return hash; - } - - /** - * Returns true if the given object is this identical - * WeakClassKey instance, or, if this object's referent has not - * been cleared, if the given object is another WeakClassKey - * instance with the identical non-null referent as this one. - */ - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof WeakClassKey) { - Object referent = get(); - return (referent != null) && - (referent == ((WeakClassKey) obj).get()); - } else { - return false; - } - } - } } diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/io/ObjectStreamConstants.java --- a/emul/compact/src/main/java/java/io/ObjectStreamConstants.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/io/ObjectStreamConstants.java Mon Jan 28 18:15:21 2013 +0100 @@ -179,26 +179,6 @@ /* *******************************************************************/ /* Security permissions */ - /** - * Enable substitution of one object for another during - * serialization/deserialization. - * - * @see java.io.ObjectOutputStream#enableReplaceObject(boolean) - * @see java.io.ObjectInputStream#enableResolveObject(boolean) - * @since 1.2 - */ - final static SerializablePermission SUBSTITUTION_PERMISSION = - new SerializablePermission("enableSubstitution"); - - /** - * Enable overriding of readObject and writeObject. - * - * @see java.io.ObjectOutputStream#writeObjectOverride(Object) - * @see java.io.ObjectInputStream#readObjectOverride() - * @since 1.2 - */ - final static SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION = - new SerializablePermission("enableSubclassImplementation"); /** * A Stream Protocol Version.

* diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/lang/ref/Reference.java --- a/emul/compact/src/main/java/java/lang/ref/Reference.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/lang/ref/Reference.java Mon Jan 28 18:15:21 2013 +0100 @@ -25,8 +25,6 @@ package java.lang.ref; -import sun.misc.Cleaner; - /** * Abstract base class for reference objects. This class defines the @@ -110,57 +108,6 @@ */ private static Reference pending = null; - /* High-priority thread to enqueue pending References - */ - private static class ReferenceHandler extends Thread { - - ReferenceHandler(ThreadGroup g, String name) { - super(g, name); - } - - public void run() { - for (;;) { - - Reference r; - synchronized (lock) { - if (pending != null) { - r = pending; - Reference rn = r.next; - pending = (rn == r) ? null : rn; - r.next = r; - } else { - try { - lock.wait(); - } catch (InterruptedException x) { } - continue; - } - } - - // Fast path for cleaners - if (r instanceof Cleaner) { - ((Cleaner)r).clean(); - continue; - } - - ReferenceQueue q = r.queue; - if (q != ReferenceQueue.NULL) q.enqueue(r); - } - } - } - - static { - ThreadGroup tg = Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - Thread handler = new ReferenceHandler(tg, "Reference Handler"); - /* If there were a special system-only priority greater than - * MAX_PRIORITY, it would be used here - */ - handler.setPriority(Thread.MAX_PRIORITY); - handler.setDaemon(true); - handler.start(); - } /* -- Referent accessor and setters -- */ diff -r 3d10a6d55653 -r 3fcc279c921b emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java --- a/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java Mon Jan 28 18:15:21 2013 +0100 @@ -62,9 +62,6 @@ r.next = (head == null) ? r : head; head = r; queueLength++; - if (r instanceof FinalReference) { - sun.misc.VM.addFinalRefCount(1); - } lock.notifyAll(); return true; } @@ -78,9 +75,6 @@ r.queue = NULL; r.next = r; queueLength--; - if (r instanceof FinalReference) { - sun.misc.VM.addFinalRefCount(-1); - } return r; } return null; diff -r 3d10a6d55653 -r 3fcc279c921b emul/mini/src/main/java/java/lang/Class.java --- a/emul/mini/src/main/java/java/lang/Class.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/Class.java Mon Jan 28 18:15:21 2013 +0100 @@ -909,7 +909,50 @@ } return m; } - + + /** + * Returns an array of {@code Method} objects reflecting all the + * methods declared by the class or interface represented by this + * {@code Class} object. This includes public, protected, default + * (package) access, and private methods, but excludes inherited methods. + * The elements in the array returned are not sorted and are not in any + * particular order. This method returns an array of length 0 if the class + * or interface declares no methods, or if this {@code Class} object + * represents a primitive type, an array class, or void. The class + * initialization method {@code } is not included in the + * returned array. If the class declares multiple public member methods + * with the same parameter types, they are all included in the returned + * array. + * + *

See The Java Language Specification, section 8.2. + * + * @return the array of {@code Method} objects representing all the + * declared methods of this class + * @exception SecurityException + * If a security manager, s, is present and any of the + * following conditions is met: + * + *

    + * + *
  • invocation of + * {@link SecurityManager#checkMemberAccess + * s.checkMemberAccess(this, Member.DECLARED)} denies + * access to the declared methods within this class + * + *
  • the caller's class loader is not the same as or an + * ancestor of the class loader for the current class and + * invocation of {@link SecurityManager#checkPackageAccess + * s.checkPackageAccess()} denies access to the package + * of this class + * + *
+ * + * @since JDK1.1 + */ + public Method[] getDeclaredMethods() throws SecurityException { + throw new SecurityException(); + } + /** * Character.isDigit answers {@code true} to some non-ascii * digits. This one does not. @@ -1096,6 +1139,48 @@ public ClassLoader getClassLoader() { throw new SecurityException(); } + + /** + * Determines the interfaces implemented by the class or interface + * represented by this object. + * + *

If this object represents a class, the return value is an array + * containing objects representing all interfaces implemented by the + * class. The order of the interface objects in the array corresponds to + * the order of the interface names in the {@code implements} clause + * of the declaration of the class represented by this object. For + * example, given the declaration: + *

+ * {@code class Shimmer implements FloorWax, DessertTopping { ... }} + *
+ * suppose the value of {@code s} is an instance of + * {@code Shimmer}; the value of the expression: + *
+ * {@code s.getClass().getInterfaces()[0]} + *
+ * is the {@code Class} object that represents interface + * {@code FloorWax}; and the value of: + *
+ * {@code s.getClass().getInterfaces()[1]} + *
+ * is the {@code Class} object that represents interface + * {@code DessertTopping}. + * + *

If this object represents an interface, the array contains objects + * representing all interfaces extended by the interface. The order of the + * interface objects in the array corresponds to the order of the interface + * names in the {@code extends} clause of the declaration of the + * interface represented by this object. + * + *

If this object represents a class or interface that implements no + * interfaces, the method returns an array of length 0. + * + *

If this object represents a primitive type or void, the method + * returns an array of length 0. + * + * @return an array of interfaces implemented by this class. + */ + public native Class[] getInterfaces(); /** * Returns the {@code Class} representing the component type of an diff -r 3d10a6d55653 -r 3fcc279c921b emul/mini/src/main/java/java/lang/reflect/Constructor.java --- a/emul/mini/src/main/java/java/lang/reflect/Constructor.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/reflect/Constructor.java Mon Jan 28 18:15:21 2013 +0100 @@ -25,17 +25,8 @@ package java.lang.reflect; -import sun.reflect.ConstructorAccessor; -import sun.reflect.Reflection; -import sun.reflect.generics.repository.ConstructorRepository; -import sun.reflect.generics.factory.CoreReflectionFactory; -import sun.reflect.generics.factory.GenericsFactory; -import sun.reflect.generics.scope.ConstructorScope; import java.lang.annotation.Annotation; -import java.util.Map; -import sun.reflect.annotation.AnnotationParser; -import java.lang.annotation.AnnotationFormatError; -import java.lang.reflect.Modifier; +import org.apidesign.bck2brwsr.emul.reflect.TypeProvider; /** * {@code Constructor} provides information about, and access to, a single @@ -69,31 +60,10 @@ private int modifiers; // Generics and annotations support private transient String signature; - // generic info repository; lazily initialized - private transient ConstructorRepository genericInfo; private byte[] annotations; private byte[] parameterAnnotations; - // Generics infrastructure - // Accessor for factory - private GenericsFactory getFactory() { - // create scope and factory - return CoreReflectionFactory.make(this, ConstructorScope.make(this)); - } - // Accessor for generic info repository - private ConstructorRepository getGenericInfo() { - // lazily initialize repository if necessary - if (genericInfo == null) { - // create and cache generic info repository - genericInfo = - ConstructorRepository.make(getSignature(), - getFactory()); - } - return genericInfo; //return cached repository - } - - private volatile ConstructorAccessor constructorAccessor; // For sharing of ConstructorAccessors. This branching structure // is currently only two levels deep (i.e., one root Constructor // and potentially many Constructor objects pointing to it.) @@ -129,23 +99,7 @@ * "root" field points to this Constructor. */ Constructor copy() { - // This routine enables sharing of ConstructorAccessor objects - // among Constructor objects which refer to the same underlying - // method in the VM. (All of this contortion is only necessary - // because of the "accessibility" bit in AccessibleObject, - // which implicitly requires that new java.lang.reflect - // objects be fabricated for each reflective call on Class - // objects.) - Constructor res = new Constructor<>(clazz, - parameterTypes, - exceptionTypes, modifiers, slot, - signature, - annotations, - parameterAnnotations); - res.root = this; - // Might as well eagerly propagate this if already present - res.constructorAccessor = constructorAccessor; - return res; + return this; } /** @@ -191,10 +145,7 @@ * @since 1.5 */ public TypeVariable>[] getTypeParameters() { - if (getSignature() != null) { - return (TypeVariable>[])getGenericInfo().getTypeParameters(); - } else - return (TypeVariable>[])new TypeVariable[0]; + return TypeProvider.getDefault().getTypeParameters(this); } @@ -240,10 +191,7 @@ * @since 1.5 */ public Type[] getGenericParameterTypes() { - if (getSignature() != null) - return getGenericInfo().getParameterTypes(); - else - return getParameterTypes(); + return TypeProvider.getDefault().getGenericParameterTypes(this); } @@ -284,12 +232,7 @@ * @since 1.5 */ public Type[] getGenericExceptionTypes() { - Type[] result; - if (getSignature() != null && - ( (result = getGenericInfo().getExceptionTypes()).length > 0 )) - return result; - else - return getExceptionTypes(); + return TypeProvider.getDefault().getGenericExceptionTypes(this); } /** @@ -509,20 +452,7 @@ throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - if (!override) { - if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class caller = Reflection.getCallerClass(2); - - checkAccess(caller, clazz, null, modifiers); - } - } - if ((clazz.getModifiers() & Modifier.ENUM) != 0) - throw new IllegalArgumentException("Cannot reflectively create enum objects"); - ConstructorAccessor ca = constructorAccessor; // read volatile - if (ca == null) { - ca = acquireConstructorAccessor(); - } - return (T) ca.newInstance(initargs); + throw new SecurityException(); } /** @@ -551,43 +481,6 @@ return Modifier.isSynthetic(getModifiers()); } - // NOTE that there is no synchronization used here. It is correct - // (though not efficient) to generate more than one - // ConstructorAccessor for a given Constructor. However, avoiding - // synchronization will probably make the implementation more - // scalable. - private ConstructorAccessor acquireConstructorAccessor() { - // First check to see if one has been created yet, and take it - // if so. - ConstructorAccessor tmp = null; - if (root != null) tmp = root.getConstructorAccessor(); - if (tmp != null) { - constructorAccessor = tmp; - } else { - // Otherwise fabricate one and propagate it up to the root - tmp = reflectionFactory.newConstructorAccessor(this); - setConstructorAccessor(tmp); - } - - return tmp; - } - - // Returns ConstructorAccessor for this Constructor object, not - // looking up the chain to the root - ConstructorAccessor getConstructorAccessor() { - return constructorAccessor; - } - - // Sets the ConstructorAccessor for this Constructor object and - // (recursively) its root - void setConstructorAccessor(ConstructorAccessor accessor) { - constructorAccessor = accessor; - // Propagate up - if (root != null) { - root.setConstructorAccessor(accessor); - } - } - int getSlot() { return slot; } @@ -612,26 +505,14 @@ if (annotationClass == null) throw new NullPointerException(); - return (T) declaredAnnotations().get(annotationClass); + return null; // XXX (T) declaredAnnotations().get(annotationClass); } /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); - } - - private transient Map, Annotation> declaredAnnotations; - - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - } - return declaredAnnotations; + return new Annotation[0]; // XXX AnnotationParser.toArray(declaredAnnotations()); } /** @@ -654,7 +535,9 @@ int numParameters = parameterTypes.length; if (parameterAnnotations == null) return new Annotation[numParameters][0]; - + + return new Annotation[numParameters][0]; // XXX +/* Annotation[][] result = AnnotationParser.parseParameterAnnotations( parameterAnnotations, sun.misc.SharedSecrets.getJavaLangAccess(). @@ -679,5 +562,6 @@ } } return result; + */ } } diff -r 3d10a6d55653 -r 3fcc279c921b emul/mini/src/main/java/java/lang/reflect/Proxy.java --- a/emul/mini/src/main/java/java/lang/reflect/Proxy.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/reflect/Proxy.java Mon Jan 28 18:15:21 2013 +0100 @@ -25,17 +25,6 @@ package java.lang.reflect; -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.List; -import java.util.WeakHashMap; -import sun.misc.ProxyGenerator; /** * {@code Proxy} provides static methods for creating dynamic proxy @@ -223,27 +212,7 @@ private static final long serialVersionUID = -2222568056686623797L; - /** prefix for all proxy class names */ - private final static String proxyClassNamePrefix = "$Proxy"; - /** parameter types of a proxy class constructor */ - private final static Class[] constructorParams = - { InvocationHandler.class }; - - /** maps a class loader to the proxy class cache for that loader */ - private static Map, Object>> loaderToCache - = new WeakHashMap<>(); - - /** marks that a particular proxy class is currently being generated */ - private static Object pendingGenerationMarker = new Object(); - - /** next number to use for generation of unique proxy class names */ - private static long nextUniqueNumber = 0; - private static Object nextUniqueNumberLock = new Object(); - - /** set of all generated proxy classes, for isProxyClass implementation */ - private static Map, Void> proxyClasses = - Collections.synchronizedMap(new WeakHashMap, Void>()); /** * the invocation handler for this proxy instance. @@ -346,215 +315,7 @@ Class... interfaces) throws IllegalArgumentException { - if (interfaces.length > 65535) { - throw new IllegalArgumentException("interface limit exceeded"); - } - - Class proxyClass = null; - - /* collect interface names to use as key for proxy class cache */ - String[] interfaceNames = new String[interfaces.length]; - - // for detecting duplicates - Set> interfaceSet = new HashSet<>(); - - for (int i = 0; i < interfaces.length; i++) { - /* - * Verify that the class loader resolves the name of this - * interface to the same Class object. - */ - String interfaceName = interfaces[i].getName(); - Class interfaceClass = null; - try { - interfaceClass = Class.forName(interfaceName, false, loader); - } catch (ClassNotFoundException e) { - } - if (interfaceClass != interfaces[i]) { - throw new IllegalArgumentException( - interfaces[i] + " is not visible from class loader"); - } - - /* - * Verify that the Class object actually represents an - * interface. - */ - if (!interfaceClass.isInterface()) { - throw new IllegalArgumentException( - interfaceClass.getName() + " is not an interface"); - } - - /* - * Verify that this interface is not a duplicate. - */ - if (interfaceSet.contains(interfaceClass)) { - throw new IllegalArgumentException( - "repeated interface: " + interfaceClass.getName()); - } - interfaceSet.add(interfaceClass); - - interfaceNames[i] = interfaceName; - } - - /* - * Using string representations of the proxy interfaces as - * keys in the proxy class cache (instead of their Class - * objects) is sufficient because we require the proxy - * interfaces to be resolvable by name through the supplied - * class loader, and it has the advantage that using a string - * representation of a class makes for an implicit weak - * reference to the class. - */ - List key = Arrays.asList(interfaceNames); - - /* - * Find or create the proxy class cache for the class loader. - */ - Map, Object> cache; - synchronized (loaderToCache) { - cache = loaderToCache.get(loader); - if (cache == null) { - cache = new HashMap<>(); - loaderToCache.put(loader, cache); - } - /* - * This mapping will remain valid for the duration of this - * method, without further synchronization, because the mapping - * will only be removed if the class loader becomes unreachable. - */ - } - - /* - * Look up the list of interfaces in the proxy class cache using - * the key. This lookup will result in one of three possible - * kinds of values: - * null, if there is currently no proxy class for the list of - * interfaces in the class loader, - * the pendingGenerationMarker object, if a proxy class for the - * list of interfaces is currently being generated, - * or a weak reference to a Class object, if a proxy class for - * the list of interfaces has already been generated. - */ - synchronized (cache) { - /* - * Note that we need not worry about reaping the cache for - * entries with cleared weak references because if a proxy class - * has been garbage collected, its class loader will have been - * garbage collected as well, so the entire cache will be reaped - * from the loaderToCache map. - */ - do { - Object value = cache.get(key); - if (value instanceof Reference) { - proxyClass = (Class) ((Reference) value).get(); - } - if (proxyClass != null) { - // proxy class already generated: return it - return proxyClass; - } else if (value == pendingGenerationMarker) { - // proxy class being generated: wait for it - try { - cache.wait(); - } catch (InterruptedException e) { - /* - * The class generation that we are waiting for should - * take a small, bounded time, so we can safely ignore - * thread interrupts here. - */ - } - continue; - } else { - /* - * No proxy class for this list of interfaces has been - * generated or is being generated, so we will go and - * generate it now. Mark it as pending generation. - */ - cache.put(key, pendingGenerationMarker); - break; - } - } while (true); - } - - try { - String proxyPkg = null; // package to define proxy class in - - /* - * Record the package of a non-public proxy interface so that the - * proxy class will be defined in the same package. Verify that - * all non-public proxy interfaces are in the same package. - */ - for (int i = 0; i < interfaces.length; i++) { - int flags = interfaces[i].getModifiers(); - if (!Modifier.isPublic(flags)) { - String name = interfaces[i].getName(); - int n = name.lastIndexOf('.'); - String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); - if (proxyPkg == null) { - proxyPkg = pkg; - } else if (!pkg.equals(proxyPkg)) { - throw new IllegalArgumentException( - "non-public interfaces from different packages"); - } - } - } - - if (proxyPkg == null) { // if no non-public proxy interfaces, - proxyPkg = ""; // use the unnamed package - } - - { - /* - * Choose a name for the proxy class to generate. - */ - long num; - synchronized (nextUniqueNumberLock) { - num = nextUniqueNumber++; - } - String proxyName = proxyPkg + proxyClassNamePrefix + num; - /* - * Verify that the class loader hasn't already - * defined a class with the chosen name. - */ - - /* - * Generate the specified proxy class. - */ - byte[] proxyClassFile = ProxyGenerator.generateProxyClass( - proxyName, interfaces); - try { - proxyClass = defineClass0(loader, proxyName, - proxyClassFile, 0, proxyClassFile.length); - } catch (ClassFormatError e) { - /* - * A ClassFormatError here means that (barring bugs in the - * proxy class generation code) there was some other - * invalid aspect of the arguments supplied to the proxy - * class creation (such as virtual machine limitations - * exceeded). - */ - throw new IllegalArgumentException(e.toString()); - } - } - // add to set of all generated proxy classes, for isProxyClass - proxyClasses.put(proxyClass, null); - - } finally { - /* - * We must clean up the "pending generation" state of the proxy - * class cache entry somehow. If a proxy class was successfully - * generated, store it in the cache (with a weak reference); - * otherwise, remove the reserved entry. In all cases, notify - * all waiters on reserved entries in this cache. - */ - synchronized (cache) { - if (proxyClass != null) { - cache.put(key, new WeakReference>(proxyClass)); - } else { - cache.remove(key); - } - cache.notifyAll(); - } - } - return proxyClass; + throw new IllegalArgumentException(); } /** @@ -594,27 +355,7 @@ if (h == null) { throw new NullPointerException(); } - - /* - * Look up or generate the designated proxy class. - */ - Class cl = getProxyClass(loader, interfaces); - - /* - * Invoke its constructor with the designated invocation handler. - */ - try { - Constructor cons = cl.getConstructor(constructorParams); - return cons.newInstance(new Object[] { h }); - } catch (NoSuchMethodException e) { - throw new InternalError(e.toString()); - } catch (IllegalAccessException e) { - throw new InternalError(e.toString()); - } catch (InstantiationException e) { - throw new InternalError(e.toString()); - } catch (InvocationTargetException e) { - throw new InternalError(e.toString()); - } + throw new IllegalArgumentException(); } /** @@ -636,7 +377,7 @@ throw new NullPointerException(); } - return proxyClasses.containsKey(cl); + return false; } /** diff -r 3d10a6d55653 -r 3fcc279c921b emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Mon Jan 28 18:15:21 2013 +0100 @@ -47,4 +47,8 @@ @JavaScriptBody(args = {}, body = "new Date().getMilliseconds() * 1000;") public static native long nanoTime(); + + @JavaScriptBody(args = { "obj" }, body="return vm.java_lang_Object(false).hashCode__I.call(obj);") + public static native int identityHashCode(Object obj); + } diff -r 3d10a6d55653 -r 3fcc279c921b emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java Mon Jan 28 18:14:14 2013 +0100 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java Mon Jan 28 18:15:21 2013 +0100 @@ -1,26 +1,19 @@ -/* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. */ package org.apidesign.bck2brwsr.emul.reflect; diff -r 3d10a6d55653 -r 3fcc279c921b emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/TypeProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/TypeProvider.java Mon Jan 28 18:15:21 2013 +0100 @@ -0,0 +1,40 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.emul.reflect; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +/** + * + * @author Jaroslav Tulach + */ +public abstract class TypeProvider { + private TypeProvider() { + } + + public static TypeProvider getDefault() { + return null; + } + + public abstract TypeVariable>[] getTypeParameters(Constructor c); + public abstract Type[] getGenericParameterTypes(Constructor c); + public abstract Type[] getGenericExceptionTypes(Constructor c); + +}