Making new clases (mostly java.io.Object*) compilable emul
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 28 Jan 2013 18:15:21 +0100
branchemul
changeset 6043fcc279c921b
parent 603 3d10a6d55653
child 606 146b81b14ac6
Making new clases (mostly java.io.Object*) compilable
emul/compact/src/main/java/java/beans/ChangeListenerMap.java
emul/compact/src/main/java/java/beans/VetoableChangeSupport.java
emul/compact/src/main/java/java/io/ObjectInputStream.java
emul/compact/src/main/java/java/io/ObjectOutputStream.java
emul/compact/src/main/java/java/io/ObjectStreamClass.java
emul/compact/src/main/java/java/io/ObjectStreamConstants.java
emul/compact/src/main/java/java/lang/ref/Reference.java
emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java
emul/mini/src/main/java/java/lang/Class.java
emul/mini/src/main/java/java/lang/reflect/Constructor.java
emul/mini/src/main/java/java/lang/reflect/Proxy.java
emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java
emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java
emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/TypeProvider.java
     1.1 --- a/emul/compact/src/main/java/java/beans/ChangeListenerMap.java	Mon Jan 28 18:14:14 2013 +0100
     1.2 +++ b/emul/compact/src/main/java/java/beans/ChangeListenerMap.java	Mon Jan 28 18:15:21 2013 +0100
     1.3 @@ -33,6 +33,7 @@
     1.4  import java.util.Map;
     1.5  import java.util.Map.Entry;
     1.6  import java.util.Set;
     1.7 +import org.apidesign.bck2brwsr.emul.lang.System;
     1.8  
     1.9  /**
    1.10   * This is an abstract class that provides base functionality
     2.1 --- a/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java	Mon Jan 28 18:14:14 2013 +0100
     2.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java	Mon Jan 28 18:15:21 2013 +0100
     2.3 @@ -31,6 +31,7 @@
     2.4  import java.io.IOException;
     2.5  import java.util.Hashtable;
     2.6  import java.util.Map.Entry;
     2.7 +import org.apidesign.bck2brwsr.emul.lang.System;
     2.8  
     2.9  /**
    2.10   * This is a utility class that can be used by beans that support constrained
     3.1 --- a/emul/compact/src/main/java/java/io/ObjectInputStream.java	Mon Jan 28 18:14:14 2013 +0100
     3.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputStream.java	Mon Jan 28 18:15:21 2013 +0100
     3.3 @@ -25,22 +25,12 @@
     3.4  
     3.5  package java.io;
     3.6  
     3.7 -import java.io.ObjectStreamClass.WeakClassKey;
     3.8 -import java.lang.ref.ReferenceQueue;
     3.9  import java.lang.reflect.Array;
    3.10  import java.lang.reflect.Modifier;
    3.11  import java.lang.reflect.Proxy;
    3.12 -import java.security.AccessControlContext;
    3.13 -import java.security.AccessController;
    3.14 -import java.security.PrivilegedAction;
    3.15 -import java.security.PrivilegedActionException;
    3.16 -import java.security.PrivilegedExceptionAction;
    3.17  import java.util.Arrays;
    3.18  import java.util.HashMap;
    3.19 -import java.util.concurrent.ConcurrentHashMap;
    3.20 -import java.util.concurrent.ConcurrentMap;
    3.21 -import java.util.concurrent.atomic.AtomicBoolean;
    3.22 -import static java.io.ObjectStreamClass.processQueue;
    3.23 +import org.apidesign.bck2brwsr.emul.lang.System;
    3.24  
    3.25  /**
    3.26   * An ObjectInputStream deserializes primitive data and objects previously
    3.27 @@ -226,16 +216,6 @@
    3.28          primClasses.put("void", void.class);
    3.29      }
    3.30  
    3.31 -    private static class Caches {
    3.32 -        /** cache of subclass security audit results */
    3.33 -        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
    3.34 -            new ConcurrentHashMap<>();
    3.35 -
    3.36 -        /** queue for WeakReferences to audited subclasses */
    3.37 -        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
    3.38 -            new ReferenceQueue<>();
    3.39 -    }
    3.40 -
    3.41      /** filter stream for handling block data conversion */
    3.42      private final BlockDataInputStream bin;
    3.43      /** validation callback list */
    3.44 @@ -265,7 +245,7 @@
    3.45       * object currently being deserialized and descriptor for current class.
    3.46       * Null when not during readObject upcall.
    3.47       */
    3.48 -    private SerialCallbackContext curContext;
    3.49 +    private Object curContext;
    3.50  
    3.51      /**
    3.52       * Creates an ObjectInputStream that reads from the specified InputStream.
    3.53 @@ -316,14 +296,7 @@
    3.54       * @see java.io.SerializablePermission
    3.55       */
    3.56      protected ObjectInputStream() throws IOException, SecurityException {
    3.57 -        SecurityManager sm = System.getSecurityManager();
    3.58 -        if (sm != null) {
    3.59 -            sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
    3.60 -        }
    3.61 -        bin = null;
    3.62 -        handles = null;
    3.63 -        vlist = null;
    3.64 -        enableOverride = true;
    3.65 +        throw new SecurityException();
    3.66      }
    3.67  
    3.68      /**
    3.69 @@ -359,29 +332,7 @@
    3.70      public final Object readObject()
    3.71          throws IOException, ClassNotFoundException
    3.72      {
    3.73 -        if (enableOverride) {
    3.74 -            return readObjectOverride();
    3.75 -        }
    3.76 -
    3.77 -        // if nested read, passHandle contains handle of enclosing object
    3.78 -        int outerHandle = passHandle;
    3.79 -        try {
    3.80 -            Object obj = readObject0(false);
    3.81 -            handles.markDependency(outerHandle, passHandle);
    3.82 -            ClassNotFoundException ex = handles.lookupException(passHandle);
    3.83 -            if (ex != null) {
    3.84 -                throw ex;
    3.85 -            }
    3.86 -            if (depth == 0) {
    3.87 -                vlist.doCallbacks();
    3.88 -            }
    3.89 -            return obj;
    3.90 -        } finally {
    3.91 -            passHandle = outerHandle;
    3.92 -            if (closed && depth == 0) {
    3.93 -                clear();
    3.94 -            }
    3.95 -        }
    3.96 +        throw new IOException();
    3.97      }
    3.98  
    3.99      /**
   3.100 @@ -492,8 +443,8 @@
   3.101          if (curContext == null) {
   3.102              throw new NotActiveException("not in call to readObject");
   3.103          }
   3.104 -        Object curObj = curContext.getObj();
   3.105 -        ObjectStreamClass curDesc = curContext.getDesc();
   3.106 +        Object curObj = null; // curContext.getObj();
   3.107 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
   3.108          bin.setBlockDataMode(false);
   3.109          defaultReadFields(curObj, curDesc);
   3.110          bin.setBlockDataMode(true);
   3.111 @@ -530,8 +481,8 @@
   3.112          if (curContext == null) {
   3.113              throw new NotActiveException("not in call to readObject");
   3.114          }
   3.115 -        Object curObj = curContext.getObj();
   3.116 -        ObjectStreamClass curDesc = curContext.getDesc();
   3.117 +        Object curObj = null; // curContext.getObj();
   3.118 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
   3.119          bin.setBlockDataMode(false);
   3.120          GetFieldImpl getField = new GetFieldImpl(curDesc);
   3.121          getField.readFields();
   3.122 @@ -769,17 +720,7 @@
   3.123      protected boolean enableResolveObject(boolean enable)
   3.124          throws SecurityException
   3.125      {
   3.126 -        if (enable == enableResolve) {
   3.127 -            return enable;
   3.128 -        }
   3.129 -        if (enable) {
   3.130 -            SecurityManager sm = System.getSecurityManager();
   3.131 -            if (sm != null) {
   3.132 -                sm.checkPermission(SUBSTITUTION_PERMISSION);
   3.133 -            }
   3.134 -        }
   3.135 -        enableResolve = enable;
   3.136 -        return !enableResolve;
   3.137 +        throw new SecurityException();
   3.138      }
   3.139  
   3.140      /**
   3.141 @@ -1233,53 +1174,7 @@
   3.142          if (cl == ObjectInputStream.class) {
   3.143              return;
   3.144          }
   3.145 -        SecurityManager sm = System.getSecurityManager();
   3.146 -        if (sm == null) {
   3.147 -            return;
   3.148 -        }
   3.149 -        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
   3.150 -        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
   3.151 -        Boolean result = Caches.subclassAudits.get(key);
   3.152 -        if (result == null) {
   3.153 -            result = Boolean.valueOf(auditSubclass(cl));
   3.154 -            Caches.subclassAudits.putIfAbsent(key, result);
   3.155 -        }
   3.156 -        if (result.booleanValue()) {
   3.157 -            return;
   3.158 -        }
   3.159 -        sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
   3.160 -    }
   3.161 -
   3.162 -    /**
   3.163 -     * Performs reflective checks on given subclass to verify that it doesn't
   3.164 -     * override security-sensitive non-final methods.  Returns true if subclass
   3.165 -     * is "safe", false otherwise.
   3.166 -     */
   3.167 -    private static boolean auditSubclass(final Class<?> subcl) {
   3.168 -        Boolean result = AccessController.doPrivileged(
   3.169 -            new PrivilegedAction<Boolean>() {
   3.170 -                public Boolean run() {
   3.171 -                    for (Class<?> cl = subcl;
   3.172 -                         cl != ObjectInputStream.class;
   3.173 -                         cl = cl.getSuperclass())
   3.174 -                    {
   3.175 -                        try {
   3.176 -                            cl.getDeclaredMethod(
   3.177 -                                "readUnshared", (Class[]) null);
   3.178 -                            return Boolean.FALSE;
   3.179 -                        } catch (NoSuchMethodException ex) {
   3.180 -                        }
   3.181 -                        try {
   3.182 -                            cl.getDeclaredMethod("readFields", (Class[]) null);
   3.183 -                            return Boolean.FALSE;
   3.184 -                        } catch (NoSuchMethodException ex) {
   3.185 -                        }
   3.186 -                    }
   3.187 -                    return Boolean.TRUE;
   3.188 -                }
   3.189 -            }
   3.190 -        );
   3.191 -        return result.booleanValue();
   3.192 +        throw new SecurityException();
   3.193      }
   3.194  
   3.195      /**
   3.196 @@ -1798,7 +1693,7 @@
   3.197      private void readExternalData(Externalizable obj, ObjectStreamClass desc)
   3.198          throws IOException
   3.199      {
   3.200 -        SerialCallbackContext oldContext = curContext;
   3.201 +        Object oldContext = curContext;
   3.202          curContext = null;
   3.203          try {
   3.204              boolean blocked = desc.hasBlockExternalData();
   3.205 @@ -1857,10 +1752,10 @@
   3.206                      slotDesc.hasReadObjectMethod() &&
   3.207                      handles.lookupException(passHandle) == null)
   3.208                  {
   3.209 -                    SerialCallbackContext oldContext = curContext;
   3.210 +                    Object oldContext = curContext;
   3.211  
   3.212                      try {
   3.213 -                        curContext = new SerialCallbackContext(obj, slotDesc);
   3.214 +                        curContext = null; //new SerialCallbackContext(obj, slotDesc);
   3.215  
   3.216                          bin.setBlockDataMode(true);
   3.217                          slotDesc.invokeReadObject(obj, this);
   3.218 @@ -1874,7 +1769,7 @@
   3.219                           */
   3.220                          handles.markException(passHandle, ex);
   3.221                      } finally {
   3.222 -                        curContext.setUsed();
   3.223 +                        //curContext.setUsed();
   3.224                          curContext = oldContext;
   3.225                      }
   3.226  
   3.227 @@ -2158,24 +2053,6 @@
   3.228       */
   3.229      private static class ValidationList {
   3.230  
   3.231 -        private static class Callback {
   3.232 -            final ObjectInputValidation obj;
   3.233 -            final int priority;
   3.234 -            Callback next;
   3.235 -            final AccessControlContext acc;
   3.236 -
   3.237 -            Callback(ObjectInputValidation obj, int priority, Callback next,
   3.238 -                AccessControlContext acc)
   3.239 -            {
   3.240 -                this.obj = obj;
   3.241 -                this.priority = priority;
   3.242 -                this.next = next;
   3.243 -                this.acc = acc;
   3.244 -            }
   3.245 -        }
   3.246 -
   3.247 -        /** linked list of callbacks */
   3.248 -        private Callback list;
   3.249  
   3.250          /**
   3.251           * Creates new (empty) ValidationList.
   3.252 @@ -2193,18 +2070,7 @@
   3.253              if (obj == null) {
   3.254                  throw new InvalidObjectException("null callback");
   3.255              }
   3.256 -
   3.257 -            Callback prev = null, cur = list;
   3.258 -            while (cur != null && priority < cur.priority) {
   3.259 -                prev = cur;
   3.260 -                cur = cur.next;
   3.261 -            }
   3.262 -            AccessControlContext acc = AccessController.getContext();
   3.263 -            if (prev != null) {
   3.264 -                prev.next = new Callback(obj, priority, cur, acc);
   3.265 -            } else {
   3.266 -                list = new Callback(obj, priority, list, acc);
   3.267 -            }
   3.268 +            throw new InvalidObjectException("Does not work.");
   3.269          }
   3.270  
   3.271          /**
   3.272 @@ -2215,29 +2081,12 @@
   3.273           * and the exception propagated upwards.
   3.274           */
   3.275          void doCallbacks() throws InvalidObjectException {
   3.276 -            try {
   3.277 -                while (list != null) {
   3.278 -                    AccessController.doPrivileged(
   3.279 -                        new PrivilegedExceptionAction<Void>()
   3.280 -                    {
   3.281 -                        public Void run() throws InvalidObjectException {
   3.282 -                            list.obj.validateObject();
   3.283 -                            return null;
   3.284 -                        }
   3.285 -                    }, list.acc);
   3.286 -                    list = list.next;
   3.287 -                }
   3.288 -            } catch (PrivilegedActionException ex) {
   3.289 -                list = null;
   3.290 -                throw (InvalidObjectException) ex.getException();
   3.291 -            }
   3.292          }
   3.293  
   3.294          /**
   3.295           * Resets the callback list to its initial (empty) state.
   3.296           */
   3.297          public void clear() {
   3.298 -            list = null;
   3.299          }
   3.300      }
   3.301  
     4.1 --- a/emul/compact/src/main/java/java/io/ObjectOutputStream.java	Mon Jan 28 18:14:14 2013 +0100
     4.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutputStream.java	Mon Jan 28 18:15:21 2013 +0100
     4.3 @@ -25,17 +25,10 @@
     4.4  
     4.5  package java.io;
     4.6  
     4.7 -import java.io.ObjectStreamClass.WeakClassKey;
     4.8 -import java.lang.ref.ReferenceQueue;
     4.9 -import java.security.AccessController;
    4.10 -import java.security.PrivilegedAction;
    4.11  import java.util.ArrayList;
    4.12  import java.util.Arrays;
    4.13  import java.util.List;
    4.14 -import java.util.concurrent.ConcurrentHashMap;
    4.15 -import java.util.concurrent.ConcurrentMap;
    4.16 -import static java.io.ObjectStreamClass.processQueue;
    4.17 -import java.io.SerialCallbackContext;
    4.18 +import org.apidesign.bck2brwsr.emul.lang.System;
    4.19  
    4.20  /**
    4.21   * An ObjectOutputStream writes primitive data types and graphs of Java objects
    4.22 @@ -161,17 +154,6 @@
    4.23  public class ObjectOutputStream
    4.24      extends OutputStream implements ObjectOutput, ObjectStreamConstants
    4.25  {
    4.26 -
    4.27 -    private static class Caches {
    4.28 -        /** cache of subclass security audit results */
    4.29 -        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
    4.30 -            new ConcurrentHashMap<>();
    4.31 -
    4.32 -        /** queue for WeakReferences to audited subclasses */
    4.33 -        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
    4.34 -            new ReferenceQueue<>();
    4.35 -    }
    4.36 -
    4.37      /** filter stream for handling block data conversion */
    4.38      private final BlockDataOutputStream bout;
    4.39      /** obj -> wire handle map */
    4.40 @@ -197,7 +179,7 @@
    4.41       * object currently being serialized and descriptor for current class.
    4.42       * Null when not during writeObject upcall.
    4.43       */
    4.44 -    private SerialCallbackContext curContext;
    4.45 +    private Object curContext;
    4.46      /** current PutField object */
    4.47      private PutFieldImpl curPut;
    4.48  
    4.49 @@ -208,10 +190,7 @@
    4.50       * value of "sun.io.serialization.extendedDebugInfo" property,
    4.51       * as true or false for extended information about exception's place
    4.52       */
    4.53 -    private static final boolean extendedDebugInfo =
    4.54 -        java.security.AccessController.doPrivileged(
    4.55 -            new sun.security.action.GetBooleanAction(
    4.56 -                "sun.io.serialization.extendedDebugInfo")).booleanValue();
    4.57 +    private static final boolean extendedDebugInfo = false;
    4.58  
    4.59      /**
    4.60       * Creates an ObjectOutputStream that writes to the specified OutputStream.
    4.61 @@ -268,15 +247,7 @@
    4.62       * @see java.io.SerializablePermission
    4.63       */
    4.64      protected ObjectOutputStream() throws IOException, SecurityException {
    4.65 -        SecurityManager sm = System.getSecurityManager();
    4.66 -        if (sm != null) {
    4.67 -            sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
    4.68 -        }
    4.69 -        bout = null;
    4.70 -        handles = null;
    4.71 -        subs = null;
    4.72 -        enableOverride = true;
    4.73 -        debugInfoStack = null;
    4.74 +        throw new SecurityException();
    4.75      }
    4.76  
    4.77      /**
    4.78 @@ -432,8 +403,8 @@
    4.79          if ( curContext == null ) {
    4.80              throw new NotActiveException("not in call to writeObject");
    4.81          }
    4.82 -        Object curObj = curContext.getObj();
    4.83 -        ObjectStreamClass curDesc = curContext.getDesc();
    4.84 +        Object curObj = null; // curContext.getObj();
    4.85 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
    4.86          bout.setBlockDataMode(false);
    4.87          defaultWriteFields(curObj, curDesc);
    4.88          bout.setBlockDataMode(true);
    4.89 @@ -454,8 +425,8 @@
    4.90              if (curContext == null) {
    4.91                  throw new NotActiveException("not in call to writeObject");
    4.92              }
    4.93 -            Object curObj = curContext.getObj();
    4.94 -            ObjectStreamClass curDesc = curContext.getDesc();
    4.95 +            Object curObj = null; // curContext.getObj();
    4.96 +            ObjectStreamClass curDesc = null; // curContext.getDesc();
    4.97              curPut = new PutFieldImpl(curDesc);
    4.98          }
    4.99          return curPut;
   4.100 @@ -607,17 +578,7 @@
   4.101      protected boolean enableReplaceObject(boolean enable)
   4.102          throws SecurityException
   4.103      {
   4.104 -        if (enable == enableReplace) {
   4.105 -            return enable;
   4.106 -        }
   4.107 -        if (enable) {
   4.108 -            SecurityManager sm = System.getSecurityManager();
   4.109 -            if (sm != null) {
   4.110 -                sm.checkPermission(SUBSTITUTION_PERMISSION);
   4.111 -            }
   4.112 -        }
   4.113 -        enableReplace = enable;
   4.114 -        return !enableReplace;
   4.115 +        throw new SecurityException();
   4.116      }
   4.117  
   4.118      /**
   4.119 @@ -1038,53 +999,7 @@
   4.120          if (cl == ObjectOutputStream.class) {
   4.121              return;
   4.122          }
   4.123 -        SecurityManager sm = System.getSecurityManager();
   4.124 -        if (sm == null) {
   4.125 -            return;
   4.126 -        }
   4.127 -        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
   4.128 -        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
   4.129 -        Boolean result = Caches.subclassAudits.get(key);
   4.130 -        if (result == null) {
   4.131 -            result = Boolean.valueOf(auditSubclass(cl));
   4.132 -            Caches.subclassAudits.putIfAbsent(key, result);
   4.133 -        }
   4.134 -        if (result.booleanValue()) {
   4.135 -            return;
   4.136 -        }
   4.137 -        sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
   4.138 -    }
   4.139 -
   4.140 -    /**
   4.141 -     * Performs reflective checks on given subclass to verify that it doesn't
   4.142 -     * override security-sensitive non-final methods.  Returns true if subclass
   4.143 -     * is "safe", false otherwise.
   4.144 -     */
   4.145 -    private static boolean auditSubclass(final Class subcl) {
   4.146 -        Boolean result = AccessController.doPrivileged(
   4.147 -            new PrivilegedAction<Boolean>() {
   4.148 -                public Boolean run() {
   4.149 -                    for (Class cl = subcl;
   4.150 -                         cl != ObjectOutputStream.class;
   4.151 -                         cl = cl.getSuperclass())
   4.152 -                    {
   4.153 -                        try {
   4.154 -                            cl.getDeclaredMethod(
   4.155 -                                "writeUnshared", new Class[] { Object.class });
   4.156 -                            return Boolean.FALSE;
   4.157 -                        } catch (NoSuchMethodException ex) {
   4.158 -                        }
   4.159 -                        try {
   4.160 -                            cl.getDeclaredMethod("putFields", (Class[]) null);
   4.161 -                            return Boolean.FALSE;
   4.162 -                        } catch (NoSuchMethodException ex) {
   4.163 -                        }
   4.164 -                    }
   4.165 -                    return Boolean.TRUE;
   4.166 -                }
   4.167 -            }
   4.168 -        );
   4.169 -        return result.booleanValue();
   4.170 +        throw new SecurityException();
   4.171      }
   4.172  
   4.173      /**
   4.174 @@ -1433,7 +1348,7 @@
   4.175          if (extendedDebugInfo) {
   4.176              debugInfoStack.push("writeExternal data");
   4.177          }
   4.178 -        SerialCallbackContext oldContext = curContext;
   4.179 +        Object oldContext = curContext;
   4.180          try {
   4.181              curContext = null;
   4.182              if (protocol == PROTOCOL_VERSION_1) {
   4.183 @@ -1467,7 +1382,7 @@
   4.184              if (slotDesc.hasWriteObjectMethod()) {
   4.185                  PutFieldImpl oldPut = curPut;
   4.186                  curPut = null;
   4.187 -                SerialCallbackContext oldContext = curContext;
   4.188 +                Object oldContext = curContext;
   4.189  
   4.190                  if (extendedDebugInfo) {
   4.191                      debugInfoStack.push(
   4.192 @@ -1475,13 +1390,13 @@
   4.193                          slotDesc.getName() + "\")");
   4.194                  }
   4.195                  try {
   4.196 -                    curContext = new SerialCallbackContext(obj, slotDesc);
   4.197 +                    curContext = new Object(); //new SerialCallbackContext(obj, slotDesc);
   4.198                      bout.setBlockDataMode(true);
   4.199                      slotDesc.invokeWriteObject(obj, this);
   4.200                      bout.setBlockDataMode(false);
   4.201                      bout.writeByte(TC_ENDBLOCKDATA);
   4.202                  } finally {
   4.203 -                    curContext.setUsed();
   4.204 +                    //curContext.setUsed();
   4.205                      curContext = oldContext;
   4.206                      if (extendedDebugInfo) {
   4.207                          debugInfoStack.pop();
     5.1 --- a/emul/compact/src/main/java/java/io/ObjectStreamClass.java	Mon Jan 28 18:14:14 2013 +0100
     5.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamClass.java	Mon Jan 28 18:15:21 2013 +0100
     5.3 @@ -36,20 +36,12 @@
     5.4  import java.lang.reflect.Method;
     5.5  import java.lang.reflect.Modifier;
     5.6  import java.lang.reflect.Proxy;
     5.7 -import java.security.AccessController;
     5.8 -import java.security.MessageDigest;
     5.9 -import java.security.NoSuchAlgorithmException;
    5.10 -import java.security.PrivilegedAction;
    5.11  import java.util.ArrayList;
    5.12  import java.util.Arrays;
    5.13  import java.util.Collections;
    5.14  import java.util.Comparator;
    5.15  import java.util.HashSet;
    5.16  import java.util.Set;
    5.17 -import java.util.concurrent.ConcurrentHashMap;
    5.18 -import java.util.concurrent.ConcurrentMap;
    5.19 -import sun.misc.Unsafe;
    5.20 -import sun.reflect.ReflectionFactory;
    5.21  
    5.22  /**
    5.23   * Serialization's descriptor for classes.  It contains the name and
    5.24 @@ -76,27 +68,6 @@
    5.25      private static final ObjectStreamField[] serialPersistentFields =
    5.26          NO_FIELDS;
    5.27  
    5.28 -    /** reflection factory for obtaining serialization constructors */
    5.29 -    private static final ReflectionFactory reflFactory =
    5.30 -        AccessController.doPrivileged(
    5.31 -            new ReflectionFactory.GetReflectionFactoryAction());
    5.32 -
    5.33 -    private static class Caches {
    5.34 -        /** cache mapping local classes -> descriptors */
    5.35 -        static final ConcurrentMap<WeakClassKey,Reference<?>> localDescs =
    5.36 -            new ConcurrentHashMap<>();
    5.37 -
    5.38 -        /** cache mapping field group/local desc pairs -> field reflectors */
    5.39 -        static final ConcurrentMap<FieldReflectorKey,Reference<?>> reflectors =
    5.40 -            new ConcurrentHashMap<>();
    5.41 -
    5.42 -        /** queue for WeakReferences to local classes */
    5.43 -        private static final ReferenceQueue<Class<?>> localDescsQueue =
    5.44 -            new ReferenceQueue<>();
    5.45 -        /** queue for WeakReferences to field reflectors keys */
    5.46 -        private static final ReferenceQueue<Class<?>> reflectorsQueue =
    5.47 -            new ReferenceQueue<>();
    5.48 -    }
    5.49  
    5.50      /** class associated with this descriptor (if any) */
    5.51      private Class<?> cl;
    5.52 @@ -139,7 +110,7 @@
    5.53      /** number of non-primitive fields */
    5.54      private int numObjFields;
    5.55      /** reflector for setting/getting serializable field values */
    5.56 -    private FieldReflector fieldRefl;
    5.57 +//    private FieldReflector fieldRefl;
    5.58      /** data layout of serialized objects described by this class desc */
    5.59      private volatile ClassDataSlot[] dataLayout;
    5.60  
    5.61 @@ -216,13 +187,7 @@
    5.62      public long getSerialVersionUID() {
    5.63          // REMIND: synchronize instead of relying on volatile?
    5.64          if (suid == null) {
    5.65 -            suid = AccessController.doPrivileged(
    5.66 -                new PrivilegedAction<Long>() {
    5.67 -                    public Long run() {
    5.68 -                        return computeDefaultSUID(cl);
    5.69 -                    }
    5.70 -                }
    5.71 -            );
    5.72 +            return computeDefaultSUID(cl);
    5.73          }
    5.74          return suid.longValue();
    5.75      }
    5.76 @@ -280,26 +245,11 @@
    5.77          if (!(all || Serializable.class.isAssignableFrom(cl))) {
    5.78              return null;
    5.79          }
    5.80 -        processQueue(Caches.localDescsQueue, Caches.localDescs);
    5.81 -        WeakClassKey key = new WeakClassKey(cl, Caches.localDescsQueue);
    5.82 -        Reference<?> ref = Caches.localDescs.get(key);
    5.83          Object entry = null;
    5.84 -        if (ref != null) {
    5.85 -            entry = ref.get();
    5.86 -        }
    5.87          EntryFuture future = null;
    5.88          if (entry == null) {
    5.89              EntryFuture newEntry = new EntryFuture();
    5.90              Reference<?> newRef = new SoftReference<>(newEntry);
    5.91 -            do {
    5.92 -                if (ref != null) {
    5.93 -                    Caches.localDescs.remove(key, ref);
    5.94 -                }
    5.95 -                ref = Caches.localDescs.putIfAbsent(key, newRef);
    5.96 -                if (ref != null) {
    5.97 -                    entry = ref.get();
    5.98 -                }
    5.99 -            } while (ref != null && entry == null);
   5.100              if (entry == null) {
   5.101                  future = newEntry;
   5.102              }
   5.103 @@ -310,7 +260,7 @@
   5.104          }
   5.105          if (entry instanceof EntryFuture) {
   5.106              future = (EntryFuture) entry;
   5.107 -            if (future.getOwner() == Thread.currentThread()) {
   5.108 +            if (true) {
   5.109                  /*
   5.110                   * Handle nested call situation described by 4803747: waiting
   5.111                   * for future value to be set by a lookup() call further up the
   5.112 @@ -328,12 +278,8 @@
   5.113              } catch (Throwable th) {
   5.114                  entry = th;
   5.115              }
   5.116 -            if (future.set(entry)) {
   5.117 -                Caches.localDescs.put(key, new SoftReference<Object>(entry));
   5.118 -            } else {
   5.119 -                // nested lookup call already set future
   5.120 -                entry = future.get();
   5.121 -            }
   5.122 +            // nested lookup call already set future
   5.123 +            entry = future.get();
   5.124          }
   5.125  
   5.126          if (entry instanceof ObjectStreamClass) {
   5.127 @@ -358,7 +304,6 @@
   5.128      private static class EntryFuture {
   5.129  
   5.130          private static final Object unset = new Object();
   5.131 -        private final Thread owner = Thread.currentThread();
   5.132          private Object entry = unset;
   5.133  
   5.134          /**
   5.135 @@ -390,25 +335,8 @@
   5.136                      interrupted = true;
   5.137                  }
   5.138              }
   5.139 -            if (interrupted) {
   5.140 -                AccessController.doPrivileged(
   5.141 -                    new PrivilegedAction<Void>() {
   5.142 -                        public Void run() {
   5.143 -                            Thread.currentThread().interrupt();
   5.144 -                            return null;
   5.145 -                        }
   5.146 -                    }
   5.147 -                );
   5.148 -            }
   5.149              return entry;
   5.150          }
   5.151 -
   5.152 -        /**
   5.153 -         * Returns the thread that created this EntryFuture.
   5.154 -         */
   5.155 -        Thread getOwner() {
   5.156 -            return owner;
   5.157 -        }
   5.158      }
   5.159  
   5.160      /**
   5.161 @@ -426,60 +354,9 @@
   5.162          superDesc = (superCl != null) ? lookup(superCl, false) : null;
   5.163          localDesc = this;
   5.164  
   5.165 -        if (serializable) {
   5.166 -            AccessController.doPrivileged(new PrivilegedAction<Void>() {
   5.167 -                public Void run() {
   5.168 -                    if (isEnum) {
   5.169 -                        suid = Long.valueOf(0);
   5.170 -                        fields = NO_FIELDS;
   5.171 -                        return null;
   5.172 -                    }
   5.173 -                    if (cl.isArray()) {
   5.174 -                        fields = NO_FIELDS;
   5.175 -                        return null;
   5.176 -                    }
   5.177 +        suid = Long.valueOf(0);
   5.178 +        fields = NO_FIELDS;
   5.179  
   5.180 -                    suid = getDeclaredSUID(cl);
   5.181 -                    try {
   5.182 -                        fields = getSerialFields(cl);
   5.183 -                        computeFieldOffsets();
   5.184 -                    } catch (InvalidClassException e) {
   5.185 -                        serializeEx = deserializeEx = e;
   5.186 -                        fields = NO_FIELDS;
   5.187 -                    }
   5.188 -
   5.189 -                    if (externalizable) {
   5.190 -                        cons = getExternalizableConstructor(cl);
   5.191 -                    } else {
   5.192 -                        cons = getSerializableConstructor(cl);
   5.193 -                        writeObjectMethod = getPrivateMethod(cl, "writeObject",
   5.194 -                            new Class<?>[] { ObjectOutputStream.class },
   5.195 -                            Void.TYPE);
   5.196 -                        readObjectMethod = getPrivateMethod(cl, "readObject",
   5.197 -                            new Class<?>[] { ObjectInputStream.class },
   5.198 -                            Void.TYPE);
   5.199 -                        readObjectNoDataMethod = getPrivateMethod(
   5.200 -                            cl, "readObjectNoData", null, Void.TYPE);
   5.201 -                        hasWriteObjectData = (writeObjectMethod != null);
   5.202 -                    }
   5.203 -                    writeReplaceMethod = getInheritableMethod(
   5.204 -                        cl, "writeReplace", null, Object.class);
   5.205 -                    readResolveMethod = getInheritableMethod(
   5.206 -                        cl, "readResolve", null, Object.class);
   5.207 -                    return null;
   5.208 -                }
   5.209 -            });
   5.210 -        } else {
   5.211 -            suid = Long.valueOf(0);
   5.212 -            fields = NO_FIELDS;
   5.213 -        }
   5.214 -
   5.215 -        try {
   5.216 -            fieldRefl = getReflector(fields, this);
   5.217 -        } catch (InvalidClassException ex) {
   5.218 -            // field mismatches impossible when matching local fields vs. self
   5.219 -            throw new InternalError();
   5.220 -        }
   5.221  
   5.222          if (deserializeEx == null) {
   5.223              if (isEnum) {
   5.224 @@ -533,7 +410,6 @@
   5.225              readResolveMethod = localDesc.readResolveMethod;
   5.226              deserializeEx = localDesc.deserializeEx;
   5.227          }
   5.228 -        fieldRefl = getReflector(fields, localDesc);
   5.229      }
   5.230  
   5.231      /**
   5.232 @@ -616,9 +492,8 @@
   5.233                  deserializeEx = localDesc.deserializeEx;
   5.234              }
   5.235          }
   5.236 -        fieldRefl = getReflector(fields, localDesc);
   5.237          // reassign to matched fields so as to reflect local unshared settings
   5.238 -        fields = fieldRefl.getFields();
   5.239 +        fields = null;
   5.240      }
   5.241  
   5.242      /**
   5.243 @@ -1197,7 +1072,6 @@
   5.244       * non-null.
   5.245       */
   5.246      void getPrimFieldValues(Object obj, byte[] buf) {
   5.247 -        fieldRefl.getPrimFieldValues(obj, buf);
   5.248      }
   5.249  
   5.250      /**
   5.251 @@ -1207,7 +1081,6 @@
   5.252       * non-null.
   5.253       */
   5.254      void setPrimFieldValues(Object obj, byte[] buf) {
   5.255 -        fieldRefl.setPrimFieldValues(obj, buf);
   5.256      }
   5.257  
   5.258      /**
   5.259 @@ -1216,7 +1089,6 @@
   5.260       * the caller to ensure that obj is of the proper type if non-null.
   5.261       */
   5.262      void getObjFieldValues(Object obj, Object[] vals) {
   5.263 -        fieldRefl.getObjFieldValues(obj, vals);
   5.264      }
   5.265  
   5.266      /**
   5.267 @@ -1225,7 +1097,6 @@
   5.268       * to ensure that obj is of the proper type if non-null.
   5.269       */
   5.270      void setObjFieldValues(Object obj, Object[] vals) {
   5.271 -        fieldRefl.setObjFieldValues(obj, vals);
   5.272      }
   5.273  
   5.274      /**
   5.275 @@ -1309,14 +1180,7 @@
   5.276       * the defining class may still be non-public.
   5.277       */
   5.278      private static Constructor getExternalizableConstructor(Class<?> cl) {
   5.279 -        try {
   5.280 -            Constructor cons = cl.getDeclaredConstructor((Class<?>[]) null);
   5.281 -            cons.setAccessible(true);
   5.282 -            return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
   5.283 -                cons : null;
   5.284 -        } catch (NoSuchMethodException ex) {
   5.285 -            return null;
   5.286 -        }
   5.287 +        throw new SecurityException();
   5.288      }
   5.289  
   5.290      /**
   5.291 @@ -1331,21 +1195,7 @@
   5.292                  return null;
   5.293              }
   5.294          }
   5.295 -        try {
   5.296 -            Constructor cons = initCl.getDeclaredConstructor((Class<?>[]) null);
   5.297 -            int mods = cons.getModifiers();
   5.298 -            if ((mods & Modifier.PRIVATE) != 0 ||
   5.299 -                ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
   5.300 -                 !packageEquals(cl, initCl)))
   5.301 -            {
   5.302 -                return null;
   5.303 -            }
   5.304 -            cons = reflFactory.newConstructorForSerialization(cl, cons);
   5.305 -            cons.setAccessible(true);
   5.306 -            return cons;
   5.307 -        } catch (NoSuchMethodException ex) {
   5.308 -            return null;
   5.309 -        }
   5.310 +        throw new SecurityException();
   5.311      }
   5.312  
   5.313      /**
   5.314 @@ -1358,31 +1208,7 @@
   5.315                                                 Class<?>[] argTypes,
   5.316                                                 Class<?> returnType)
   5.317      {
   5.318 -        Method meth = null;
   5.319 -        Class<?> defCl = cl;
   5.320 -        while (defCl != null) {
   5.321 -            try {
   5.322 -                meth = defCl.getDeclaredMethod(name, argTypes);
   5.323 -                break;
   5.324 -            } catch (NoSuchMethodException ex) {
   5.325 -                defCl = defCl.getSuperclass();
   5.326 -            }
   5.327 -        }
   5.328 -
   5.329 -        if ((meth == null) || (meth.getReturnType() != returnType)) {
   5.330 -            return null;
   5.331 -        }
   5.332 -        meth.setAccessible(true);
   5.333 -        int mods = meth.getModifiers();
   5.334 -        if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
   5.335 -            return null;
   5.336 -        } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) {
   5.337 -            return meth;
   5.338 -        } else if ((mods & Modifier.PRIVATE) != 0) {
   5.339 -            return (cl == defCl) ? meth : null;
   5.340 -        } else {
   5.341 -            return packageEquals(cl, defCl) ? meth : null;
   5.342 -        }
   5.343 +        throw new SecurityException();
   5.344      }
   5.345  
   5.346      /**
   5.347 @@ -1394,16 +1220,7 @@
   5.348                                             Class<?>[] argTypes,
   5.349                                             Class<?> returnType)
   5.350      {
   5.351 -        try {
   5.352 -            Method meth = cl.getDeclaredMethod(name, argTypes);
   5.353 -            meth.setAccessible(true);
   5.354 -            int mods = meth.getModifiers();
   5.355 -            return ((meth.getReturnType() == returnType) &&
   5.356 -                    ((mods & Modifier.STATIC) == 0) &&
   5.357 -                    ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
   5.358 -        } catch (NoSuchMethodException ex) {
   5.359 -            return null;
   5.360 -        }
   5.361 +        throw new SecurityException();
   5.362      }
   5.363  
   5.364      /**
   5.365 @@ -1548,52 +1365,7 @@
   5.366      private static ObjectStreamField[] getDeclaredSerialFields(Class<?> cl)
   5.367          throws InvalidClassException
   5.368      {
   5.369 -        ObjectStreamField[] serialPersistentFields = null;
   5.370 -        try {
   5.371 -            Field f = cl.getDeclaredField("serialPersistentFields");
   5.372 -            int mask = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
   5.373 -            if ((f.getModifiers() & mask) == mask) {
   5.374 -                f.setAccessible(true);
   5.375 -                serialPersistentFields = (ObjectStreamField[]) f.get(null);
   5.376 -            }
   5.377 -        } catch (Exception ex) {
   5.378 -        }
   5.379 -        if (serialPersistentFields == null) {
   5.380 -            return null;
   5.381 -        } else if (serialPersistentFields.length == 0) {
   5.382 -            return NO_FIELDS;
   5.383 -        }
   5.384 -
   5.385 -        ObjectStreamField[] boundFields =
   5.386 -            new ObjectStreamField[serialPersistentFields.length];
   5.387 -        Set<String> fieldNames = new HashSet<>(serialPersistentFields.length);
   5.388 -
   5.389 -        for (int i = 0; i < serialPersistentFields.length; i++) {
   5.390 -            ObjectStreamField spf = serialPersistentFields[i];
   5.391 -
   5.392 -            String fname = spf.getName();
   5.393 -            if (fieldNames.contains(fname)) {
   5.394 -                throw new InvalidClassException(
   5.395 -                    "multiple serializable fields named " + fname);
   5.396 -            }
   5.397 -            fieldNames.add(fname);
   5.398 -
   5.399 -            try {
   5.400 -                Field f = cl.getDeclaredField(fname);
   5.401 -                if ((f.getType() == spf.getType()) &&
   5.402 -                    ((f.getModifiers() & Modifier.STATIC) == 0))
   5.403 -                {
   5.404 -                    boundFields[i] =
   5.405 -                        new ObjectStreamField(f, spf.isUnshared(), true);
   5.406 -                }
   5.407 -            } catch (NoSuchFieldException ex) {
   5.408 -            }
   5.409 -            if (boundFields[i] == null) {
   5.410 -                boundFields[i] = new ObjectStreamField(
   5.411 -                    fname, spf.getType(), spf.isUnshared());
   5.412 -            }
   5.413 -        }
   5.414 -        return boundFields;
   5.415 +        throw new SecurityException();
   5.416      }
   5.417  
   5.418      /**
   5.419 @@ -1603,18 +1375,7 @@
   5.420       * serializable fields exist, NO_FIELDS is returned.
   5.421       */
   5.422      private static ObjectStreamField[] getDefaultSerialFields(Class<?> cl) {
   5.423 -        Field[] clFields = cl.getDeclaredFields();
   5.424 -        ArrayList<ObjectStreamField> list = new ArrayList<>();
   5.425 -        int mask = Modifier.STATIC | Modifier.TRANSIENT;
   5.426 -
   5.427 -        for (int i = 0; i < clFields.length; i++) {
   5.428 -            if ((clFields[i].getModifiers() & mask) == 0) {
   5.429 -                list.add(new ObjectStreamField(clFields[i], false, true));
   5.430 -            }
   5.431 -        }
   5.432 -        int size = list.size();
   5.433 -        return (size == 0) ? NO_FIELDS :
   5.434 -            list.toArray(new ObjectStreamField[size]);
   5.435 +        throw new SecurityException();
   5.436      }
   5.437  
   5.438      /**
   5.439 @@ -1622,15 +1383,6 @@
   5.440       * null if none.
   5.441       */
   5.442      private static Long getDeclaredSUID(Class<?> cl) {
   5.443 -        try {
   5.444 -            Field f = cl.getDeclaredField("serialVersionUID");
   5.445 -            int mask = Modifier.STATIC | Modifier.FINAL;
   5.446 -            if ((f.getModifiers() & mask) == mask) {
   5.447 -                f.setAccessible(true);
   5.448 -                return Long.valueOf(f.getLong(null));
   5.449 -            }
   5.450 -        } catch (Exception ex) {
   5.451 -        }
   5.452          return null;
   5.453      }
   5.454  
   5.455 @@ -1638,667 +1390,7 @@
   5.456       * Computes the default serial version UID value for the given class.
   5.457       */
   5.458      private static long computeDefaultSUID(Class<?> cl) {
   5.459 -        if (!Serializable.class.isAssignableFrom(cl) || Proxy.isProxyClass(cl))
   5.460 -        {
   5.461 -            return 0L;
   5.462 -        }
   5.463 -
   5.464 -        try {
   5.465 -            ByteArrayOutputStream bout = new ByteArrayOutputStream();
   5.466 -            DataOutputStream dout = new DataOutputStream(bout);
   5.467 -
   5.468 -            dout.writeUTF(cl.getName());
   5.469 -
   5.470 -            int classMods = cl.getModifiers() &
   5.471 -                (Modifier.PUBLIC | Modifier.FINAL |
   5.472 -                 Modifier.INTERFACE | Modifier.ABSTRACT);
   5.473 -
   5.474 -            /*
   5.475 -             * compensate for javac bug in which ABSTRACT bit was set for an
   5.476 -             * interface only if the interface declared methods
   5.477 -             */
   5.478 -            Method[] methods = cl.getDeclaredMethods();
   5.479 -            if ((classMods & Modifier.INTERFACE) != 0) {
   5.480 -                classMods = (methods.length > 0) ?
   5.481 -                    (classMods | Modifier.ABSTRACT) :
   5.482 -                    (classMods & ~Modifier.ABSTRACT);
   5.483 -            }
   5.484 -            dout.writeInt(classMods);
   5.485 -
   5.486 -            if (!cl.isArray()) {
   5.487 -                /*
   5.488 -                 * compensate for change in 1.2FCS in which
   5.489 -                 * Class.getInterfaces() was modified to return Cloneable and
   5.490 -                 * Serializable for array classes.
   5.491 -                 */
   5.492 -                Class<?>[] interfaces = cl.getInterfaces();
   5.493 -                String[] ifaceNames = new String[interfaces.length];
   5.494 -                for (int i = 0; i < interfaces.length; i++) {
   5.495 -                    ifaceNames[i] = interfaces[i].getName();
   5.496 -                }
   5.497 -                Arrays.sort(ifaceNames);
   5.498 -                for (int i = 0; i < ifaceNames.length; i++) {
   5.499 -                    dout.writeUTF(ifaceNames[i]);
   5.500 -                }
   5.501 -            }
   5.502 -
   5.503 -            Field[] fields = cl.getDeclaredFields();
   5.504 -            MemberSignature[] fieldSigs = new MemberSignature[fields.length];
   5.505 -            for (int i = 0; i < fields.length; i++) {
   5.506 -                fieldSigs[i] = new MemberSignature(fields[i]);
   5.507 -            }
   5.508 -            Arrays.sort(fieldSigs, new Comparator<MemberSignature>() {
   5.509 -                public int compare(MemberSignature ms1, MemberSignature ms2) {
   5.510 -                    return ms1.name.compareTo(ms2.name);
   5.511 -                }
   5.512 -            });
   5.513 -            for (int i = 0; i < fieldSigs.length; i++) {
   5.514 -                MemberSignature sig = fieldSigs[i];
   5.515 -                int mods = sig.member.getModifiers() &
   5.516 -                    (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
   5.517 -                     Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
   5.518 -                     Modifier.TRANSIENT);
   5.519 -                if (((mods & Modifier.PRIVATE) == 0) ||
   5.520 -                    ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0))
   5.521 -                {
   5.522 -                    dout.writeUTF(sig.name);
   5.523 -                    dout.writeInt(mods);
   5.524 -                    dout.writeUTF(sig.signature);
   5.525 -                }
   5.526 -            }
   5.527 -
   5.528 -            if (hasStaticInitializer(cl)) {
   5.529 -                dout.writeUTF("<clinit>");
   5.530 -                dout.writeInt(Modifier.STATIC);
   5.531 -                dout.writeUTF("()V");
   5.532 -            }
   5.533 -
   5.534 -            Constructor[] cons = cl.getDeclaredConstructors();
   5.535 -            MemberSignature[] consSigs = new MemberSignature[cons.length];
   5.536 -            for (int i = 0; i < cons.length; i++) {
   5.537 -                consSigs[i] = new MemberSignature(cons[i]);
   5.538 -            }
   5.539 -            Arrays.sort(consSigs, new Comparator<MemberSignature>() {
   5.540 -                public int compare(MemberSignature ms1, MemberSignature ms2) {
   5.541 -                    return ms1.signature.compareTo(ms2.signature);
   5.542 -                }
   5.543 -            });
   5.544 -            for (int i = 0; i < consSigs.length; i++) {
   5.545 -                MemberSignature sig = consSigs[i];
   5.546 -                int mods = sig.member.getModifiers() &
   5.547 -                    (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
   5.548 -                     Modifier.STATIC | Modifier.FINAL |
   5.549 -                     Modifier.SYNCHRONIZED | Modifier.NATIVE |
   5.550 -                     Modifier.ABSTRACT | Modifier.STRICT);
   5.551 -                if ((mods & Modifier.PRIVATE) == 0) {
   5.552 -                    dout.writeUTF("<init>");
   5.553 -                    dout.writeInt(mods);
   5.554 -                    dout.writeUTF(sig.signature.replace('/', '.'));
   5.555 -                }
   5.556 -            }
   5.557 -
   5.558 -            MemberSignature[] methSigs = new MemberSignature[methods.length];
   5.559 -            for (int i = 0; i < methods.length; i++) {
   5.560 -                methSigs[i] = new MemberSignature(methods[i]);
   5.561 -            }
   5.562 -            Arrays.sort(methSigs, new Comparator<MemberSignature>() {
   5.563 -                public int compare(MemberSignature ms1, MemberSignature ms2) {
   5.564 -                    int comp = ms1.name.compareTo(ms2.name);
   5.565 -                    if (comp == 0) {
   5.566 -                        comp = ms1.signature.compareTo(ms2.signature);
   5.567 -                    }
   5.568 -                    return comp;
   5.569 -                }
   5.570 -            });
   5.571 -            for (int i = 0; i < methSigs.length; i++) {
   5.572 -                MemberSignature sig = methSigs[i];
   5.573 -                int mods = sig.member.getModifiers() &
   5.574 -                    (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
   5.575 -                     Modifier.STATIC | Modifier.FINAL |
   5.576 -                     Modifier.SYNCHRONIZED | Modifier.NATIVE |
   5.577 -                     Modifier.ABSTRACT | Modifier.STRICT);
   5.578 -                if ((mods & Modifier.PRIVATE) == 0) {
   5.579 -                    dout.writeUTF(sig.name);
   5.580 -                    dout.writeInt(mods);
   5.581 -                    dout.writeUTF(sig.signature.replace('/', '.'));
   5.582 -                }
   5.583 -            }
   5.584 -
   5.585 -            dout.flush();
   5.586 -
   5.587 -            MessageDigest md = MessageDigest.getInstance("SHA");
   5.588 -            byte[] hashBytes = md.digest(bout.toByteArray());
   5.589 -            long hash = 0;
   5.590 -            for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
   5.591 -                hash = (hash << 8) | (hashBytes[i] & 0xFF);
   5.592 -            }
   5.593 -            return hash;
   5.594 -        } catch (IOException ex) {
   5.595 -            throw new InternalError();
   5.596 -        } catch (NoSuchAlgorithmException ex) {
   5.597 -            throw new SecurityException(ex.getMessage());
   5.598 -        }
   5.599 +        throw new SecurityException();
   5.600      }
   5.601  
   5.602 -    /**
   5.603 -     * Returns true if the given class defines a static initializer method,
   5.604 -     * false otherwise.
   5.605 -     */
   5.606 -    private native static boolean hasStaticInitializer(Class<?> cl);
   5.607 -
   5.608 -    /**
   5.609 -     * Class for computing and caching field/constructor/method signatures
   5.610 -     * during serialVersionUID calculation.
   5.611 -     */
   5.612 -    private static class MemberSignature {
   5.613 -
   5.614 -        public final Member member;
   5.615 -        public final String name;
   5.616 -        public final String signature;
   5.617 -
   5.618 -        public MemberSignature(Field field) {
   5.619 -            member = field;
   5.620 -            name = field.getName();
   5.621 -            signature = getClassSignature(field.getType());
   5.622 -        }
   5.623 -
   5.624 -        public MemberSignature(Constructor cons) {
   5.625 -            member = cons;
   5.626 -            name = cons.getName();
   5.627 -            signature = getMethodSignature(
   5.628 -                cons.getParameterTypes(), Void.TYPE);
   5.629 -        }
   5.630 -
   5.631 -        public MemberSignature(Method meth) {
   5.632 -            member = meth;
   5.633 -            name = meth.getName();
   5.634 -            signature = getMethodSignature(
   5.635 -                meth.getParameterTypes(), meth.getReturnType());
   5.636 -        }
   5.637 -    }
   5.638 -
   5.639 -    /**
   5.640 -     * Class for setting and retrieving serializable field values in batch.
   5.641 -     */
   5.642 -    // REMIND: dynamically generate these?
   5.643 -    private static class FieldReflector {
   5.644 -
   5.645 -        /** handle for performing unsafe operations */
   5.646 -        private static final Unsafe unsafe = Unsafe.getUnsafe();
   5.647 -
   5.648 -        /** fields to operate on */
   5.649 -        private final ObjectStreamField[] fields;
   5.650 -        /** number of primitive fields */
   5.651 -        private final int numPrimFields;
   5.652 -        /** unsafe field keys for reading fields - may contain dupes */
   5.653 -        private final long[] readKeys;
   5.654 -        /** unsafe fields keys for writing fields - no dupes */
   5.655 -        private final long[] writeKeys;
   5.656 -        /** field data offsets */
   5.657 -        private final int[] offsets;
   5.658 -        /** field type codes */
   5.659 -        private final char[] typeCodes;
   5.660 -        /** field types */
   5.661 -        private final Class<?>[] types;
   5.662 -
   5.663 -        /**
   5.664 -         * Constructs FieldReflector capable of setting/getting values from the
   5.665 -         * subset of fields whose ObjectStreamFields contain non-null
   5.666 -         * reflective Field objects.  ObjectStreamFields with null Fields are
   5.667 -         * treated as filler, for which get operations return default values
   5.668 -         * and set operations discard given values.
   5.669 -         */
   5.670 -        FieldReflector(ObjectStreamField[] fields) {
   5.671 -            this.fields = fields;
   5.672 -            int nfields = fields.length;
   5.673 -            readKeys = new long[nfields];
   5.674 -            writeKeys = new long[nfields];
   5.675 -            offsets = new int[nfields];
   5.676 -            typeCodes = new char[nfields];
   5.677 -            ArrayList<Class<?>> typeList = new ArrayList<>();
   5.678 -            Set<Long> usedKeys = new HashSet<>();
   5.679 -
   5.680 -
   5.681 -            for (int i = 0; i < nfields; i++) {
   5.682 -                ObjectStreamField f = fields[i];
   5.683 -                Field rf = f.getField();
   5.684 -                long key = (rf != null) ?
   5.685 -                    unsafe.objectFieldOffset(rf) : Unsafe.INVALID_FIELD_OFFSET;
   5.686 -                readKeys[i] = key;
   5.687 -                writeKeys[i] = usedKeys.add(key) ?
   5.688 -                    key : Unsafe.INVALID_FIELD_OFFSET;
   5.689 -                offsets[i] = f.getOffset();
   5.690 -                typeCodes[i] = f.getTypeCode();
   5.691 -                if (!f.isPrimitive()) {
   5.692 -                    typeList.add((rf != null) ? rf.getType() : null);
   5.693 -                }
   5.694 -            }
   5.695 -
   5.696 -            types = typeList.toArray(new Class<?>[typeList.size()]);
   5.697 -            numPrimFields = nfields - types.length;
   5.698 -        }
   5.699 -
   5.700 -        /**
   5.701 -         * Returns list of ObjectStreamFields representing fields operated on
   5.702 -         * by this reflector.  The shared/unshared values and Field objects
   5.703 -         * contained by ObjectStreamFields in the list reflect their bindings
   5.704 -         * to locally defined serializable fields.
   5.705 -         */
   5.706 -        ObjectStreamField[] getFields() {
   5.707 -            return fields;
   5.708 -        }
   5.709 -
   5.710 -        /**
   5.711 -         * Fetches the serializable primitive field values of object obj and
   5.712 -         * marshals them into byte array buf starting at offset 0.  The caller
   5.713 -         * is responsible for ensuring that obj is of the proper type.
   5.714 -         */
   5.715 -        void getPrimFieldValues(Object obj, byte[] buf) {
   5.716 -            if (obj == null) {
   5.717 -                throw new NullPointerException();
   5.718 -            }
   5.719 -            /* assuming checkDefaultSerialize() has been called on the class
   5.720 -             * descriptor this FieldReflector was obtained from, no field keys
   5.721 -             * in array should be equal to Unsafe.INVALID_FIELD_OFFSET.
   5.722 -             */
   5.723 -            for (int i = 0; i < numPrimFields; i++) {
   5.724 -                long key = readKeys[i];
   5.725 -                int off = offsets[i];
   5.726 -                switch (typeCodes[i]) {
   5.727 -                    case 'Z':
   5.728 -                        Bits.putBoolean(buf, off, unsafe.getBoolean(obj, key));
   5.729 -                        break;
   5.730 -
   5.731 -                    case 'B':
   5.732 -                        buf[off] = unsafe.getByte(obj, key);
   5.733 -                        break;
   5.734 -
   5.735 -                    case 'C':
   5.736 -                        Bits.putChar(buf, off, unsafe.getChar(obj, key));
   5.737 -                        break;
   5.738 -
   5.739 -                    case 'S':
   5.740 -                        Bits.putShort(buf, off, unsafe.getShort(obj, key));
   5.741 -                        break;
   5.742 -
   5.743 -                    case 'I':
   5.744 -                        Bits.putInt(buf, off, unsafe.getInt(obj, key));
   5.745 -                        break;
   5.746 -
   5.747 -                    case 'F':
   5.748 -                        Bits.putFloat(buf, off, unsafe.getFloat(obj, key));
   5.749 -                        break;
   5.750 -
   5.751 -                    case 'J':
   5.752 -                        Bits.putLong(buf, off, unsafe.getLong(obj, key));
   5.753 -                        break;
   5.754 -
   5.755 -                    case 'D':
   5.756 -                        Bits.putDouble(buf, off, unsafe.getDouble(obj, key));
   5.757 -                        break;
   5.758 -
   5.759 -                    default:
   5.760 -                        throw new InternalError();
   5.761 -                }
   5.762 -            }
   5.763 -        }
   5.764 -
   5.765 -        /**
   5.766 -         * Sets the serializable primitive fields of object obj using values
   5.767 -         * unmarshalled from byte array buf starting at offset 0.  The caller
   5.768 -         * is responsible for ensuring that obj is of the proper type.
   5.769 -         */
   5.770 -        void setPrimFieldValues(Object obj, byte[] buf) {
   5.771 -            if (obj == null) {
   5.772 -                throw new NullPointerException();
   5.773 -            }
   5.774 -            for (int i = 0; i < numPrimFields; i++) {
   5.775 -                long key = writeKeys[i];
   5.776 -                if (key == Unsafe.INVALID_FIELD_OFFSET) {
   5.777 -                    continue;           // discard value
   5.778 -                }
   5.779 -                int off = offsets[i];
   5.780 -                switch (typeCodes[i]) {
   5.781 -                    case 'Z':
   5.782 -                        unsafe.putBoolean(obj, key, Bits.getBoolean(buf, off));
   5.783 -                        break;
   5.784 -
   5.785 -                    case 'B':
   5.786 -                        unsafe.putByte(obj, key, buf[off]);
   5.787 -                        break;
   5.788 -
   5.789 -                    case 'C':
   5.790 -                        unsafe.putChar(obj, key, Bits.getChar(buf, off));
   5.791 -                        break;
   5.792 -
   5.793 -                    case 'S':
   5.794 -                        unsafe.putShort(obj, key, Bits.getShort(buf, off));
   5.795 -                        break;
   5.796 -
   5.797 -                    case 'I':
   5.798 -                        unsafe.putInt(obj, key, Bits.getInt(buf, off));
   5.799 -                        break;
   5.800 -
   5.801 -                    case 'F':
   5.802 -                        unsafe.putFloat(obj, key, Bits.getFloat(buf, off));
   5.803 -                        break;
   5.804 -
   5.805 -                    case 'J':
   5.806 -                        unsafe.putLong(obj, key, Bits.getLong(buf, off));
   5.807 -                        break;
   5.808 -
   5.809 -                    case 'D':
   5.810 -                        unsafe.putDouble(obj, key, Bits.getDouble(buf, off));
   5.811 -                        break;
   5.812 -
   5.813 -                    default:
   5.814 -                        throw new InternalError();
   5.815 -                }
   5.816 -            }
   5.817 -        }
   5.818 -
   5.819 -        /**
   5.820 -         * Fetches the serializable object field values of object obj and
   5.821 -         * stores them in array vals starting at offset 0.  The caller is
   5.822 -         * responsible for ensuring that obj is of the proper type.
   5.823 -         */
   5.824 -        void getObjFieldValues(Object obj, Object[] vals) {
   5.825 -            if (obj == null) {
   5.826 -                throw new NullPointerException();
   5.827 -            }
   5.828 -            /* assuming checkDefaultSerialize() has been called on the class
   5.829 -             * descriptor this FieldReflector was obtained from, no field keys
   5.830 -             * in array should be equal to Unsafe.INVALID_FIELD_OFFSET.
   5.831 -             */
   5.832 -            for (int i = numPrimFields; i < fields.length; i++) {
   5.833 -                switch (typeCodes[i]) {
   5.834 -                    case 'L':
   5.835 -                    case '[':
   5.836 -                        vals[offsets[i]] = unsafe.getObject(obj, readKeys[i]);
   5.837 -                        break;
   5.838 -
   5.839 -                    default:
   5.840 -                        throw new InternalError();
   5.841 -                }
   5.842 -            }
   5.843 -        }
   5.844 -
   5.845 -        /**
   5.846 -         * Sets the serializable object fields of object obj using values from
   5.847 -         * array vals starting at offset 0.  The caller is responsible for
   5.848 -         * ensuring that obj is of the proper type; however, attempts to set a
   5.849 -         * field with a value of the wrong type will trigger an appropriate
   5.850 -         * ClassCastException.
   5.851 -         */
   5.852 -        void setObjFieldValues(Object obj, Object[] vals) {
   5.853 -            if (obj == null) {
   5.854 -                throw new NullPointerException();
   5.855 -            }
   5.856 -            for (int i = numPrimFields; i < fields.length; i++) {
   5.857 -                long key = writeKeys[i];
   5.858 -                if (key == Unsafe.INVALID_FIELD_OFFSET) {
   5.859 -                    continue;           // discard value
   5.860 -                }
   5.861 -                switch (typeCodes[i]) {
   5.862 -                    case 'L':
   5.863 -                    case '[':
   5.864 -                        Object val = vals[offsets[i]];
   5.865 -                        if (val != null &&
   5.866 -                            !types[i - numPrimFields].isInstance(val))
   5.867 -                        {
   5.868 -                            Field f = fields[i].getField();
   5.869 -                            throw new ClassCastException(
   5.870 -                                "cannot assign instance of " +
   5.871 -                                val.getClass().getName() + " to field " +
   5.872 -                                f.getDeclaringClass().getName() + "." +
   5.873 -                                f.getName() + " of type " +
   5.874 -                                f.getType().getName() + " in instance of " +
   5.875 -                                obj.getClass().getName());
   5.876 -                        }
   5.877 -                        unsafe.putObject(obj, key, val);
   5.878 -                        break;
   5.879 -
   5.880 -                    default:
   5.881 -                        throw new InternalError();
   5.882 -                }
   5.883 -            }
   5.884 -        }
   5.885 -    }
   5.886 -
   5.887 -    /**
   5.888 -     * Matches given set of serializable fields with serializable fields
   5.889 -     * described by the given local class descriptor, and returns a
   5.890 -     * FieldReflector instance capable of setting/getting values from the
   5.891 -     * subset of fields that match (non-matching fields are treated as filler,
   5.892 -     * for which get operations return default values and set operations
   5.893 -     * discard given values).  Throws InvalidClassException if unresolvable
   5.894 -     * type conflicts exist between the two sets of fields.
   5.895 -     */
   5.896 -    private static FieldReflector getReflector(ObjectStreamField[] fields,
   5.897 -                                               ObjectStreamClass localDesc)
   5.898 -        throws InvalidClassException
   5.899 -    {
   5.900 -        // class irrelevant if no fields
   5.901 -        Class<?> cl = (localDesc != null && fields.length > 0) ?
   5.902 -            localDesc.cl : null;
   5.903 -        processQueue(Caches.reflectorsQueue, Caches.reflectors);
   5.904 -        FieldReflectorKey key = new FieldReflectorKey(cl, fields,
   5.905 -                                                      Caches.reflectorsQueue);
   5.906 -        Reference<?> ref = Caches.reflectors.get(key);
   5.907 -        Object entry = null;
   5.908 -        if (ref != null) {
   5.909 -            entry = ref.get();
   5.910 -        }
   5.911 -        EntryFuture future = null;
   5.912 -        if (entry == null) {
   5.913 -            EntryFuture newEntry = new EntryFuture();
   5.914 -            Reference<?> newRef = new SoftReference<>(newEntry);
   5.915 -            do {
   5.916 -                if (ref != null) {
   5.917 -                    Caches.reflectors.remove(key, ref);
   5.918 -                }
   5.919 -                ref = Caches.reflectors.putIfAbsent(key, newRef);
   5.920 -                if (ref != null) {
   5.921 -                    entry = ref.get();
   5.922 -                }
   5.923 -            } while (ref != null && entry == null);
   5.924 -            if (entry == null) {
   5.925 -                future = newEntry;
   5.926 -            }
   5.927 -        }
   5.928 -
   5.929 -        if (entry instanceof FieldReflector) {  // check common case first
   5.930 -            return (FieldReflector) entry;
   5.931 -        } else if (entry instanceof EntryFuture) {
   5.932 -            entry = ((EntryFuture) entry).get();
   5.933 -        } else if (entry == null) {
   5.934 -            try {
   5.935 -                entry = new FieldReflector(matchFields(fields, localDesc));
   5.936 -            } catch (Throwable th) {
   5.937 -                entry = th;
   5.938 -            }
   5.939 -            future.set(entry);
   5.940 -            Caches.reflectors.put(key, new SoftReference<Object>(entry));
   5.941 -        }
   5.942 -
   5.943 -        if (entry instanceof FieldReflector) {
   5.944 -            return (FieldReflector) entry;
   5.945 -        } else if (entry instanceof InvalidClassException) {
   5.946 -            throw (InvalidClassException) entry;
   5.947 -        } else if (entry instanceof RuntimeException) {
   5.948 -            throw (RuntimeException) entry;
   5.949 -        } else if (entry instanceof Error) {
   5.950 -            throw (Error) entry;
   5.951 -        } else {
   5.952 -            throw new InternalError("unexpected entry: " + entry);
   5.953 -        }
   5.954 -    }
   5.955 -
   5.956 -    /**
   5.957 -     * FieldReflector cache lookup key.  Keys are considered equal if they
   5.958 -     * refer to the same class and equivalent field formats.
   5.959 -     */
   5.960 -    private static class FieldReflectorKey extends WeakReference<Class<?>> {
   5.961 -
   5.962 -        private final String sigs;
   5.963 -        private final int hash;
   5.964 -        private final boolean nullClass;
   5.965 -
   5.966 -        FieldReflectorKey(Class<?> cl, ObjectStreamField[] fields,
   5.967 -                          ReferenceQueue<Class<?>> queue)
   5.968 -        {
   5.969 -            super(cl, queue);
   5.970 -            nullClass = (cl == null);
   5.971 -            StringBuilder sbuf = new StringBuilder();
   5.972 -            for (int i = 0; i < fields.length; i++) {
   5.973 -                ObjectStreamField f = fields[i];
   5.974 -                sbuf.append(f.getName()).append(f.getSignature());
   5.975 -            }
   5.976 -            sigs = sbuf.toString();
   5.977 -            hash = System.identityHashCode(cl) + sigs.hashCode();
   5.978 -        }
   5.979 -
   5.980 -        public int hashCode() {
   5.981 -            return hash;
   5.982 -        }
   5.983 -
   5.984 -        public boolean equals(Object obj) {
   5.985 -            if (obj == this) {
   5.986 -                return true;
   5.987 -            }
   5.988 -
   5.989 -            if (obj instanceof FieldReflectorKey) {
   5.990 -                FieldReflectorKey other = (FieldReflectorKey) obj;
   5.991 -                Class<?> referent;
   5.992 -                return (nullClass ? other.nullClass
   5.993 -                                  : ((referent = get()) != null) &&
   5.994 -                                    (referent == other.get())) &&
   5.995 -                    sigs.equals(other.sigs);
   5.996 -            } else {
   5.997 -                return false;
   5.998 -            }
   5.999 -        }
  5.1000 -    }
  5.1001 -
  5.1002 -    /**
  5.1003 -     * Matches given set of serializable fields with serializable fields
  5.1004 -     * obtained from the given local class descriptor (which contain bindings
  5.1005 -     * to reflective Field objects).  Returns list of ObjectStreamFields in
  5.1006 -     * which each ObjectStreamField whose signature matches that of a local
  5.1007 -     * field contains a Field object for that field; unmatched
  5.1008 -     * ObjectStreamFields contain null Field objects.  Shared/unshared settings
  5.1009 -     * of the returned ObjectStreamFields also reflect those of matched local
  5.1010 -     * ObjectStreamFields.  Throws InvalidClassException if unresolvable type
  5.1011 -     * conflicts exist between the two sets of fields.
  5.1012 -     */
  5.1013 -    private static ObjectStreamField[] matchFields(ObjectStreamField[] fields,
  5.1014 -                                                   ObjectStreamClass localDesc)
  5.1015 -        throws InvalidClassException
  5.1016 -    {
  5.1017 -        ObjectStreamField[] localFields = (localDesc != null) ?
  5.1018 -            localDesc.fields : NO_FIELDS;
  5.1019 -
  5.1020 -        /*
  5.1021 -         * Even if fields == localFields, we cannot simply return localFields
  5.1022 -         * here.  In previous implementations of serialization,
  5.1023 -         * ObjectStreamField.getType() returned Object.class if the
  5.1024 -         * ObjectStreamField represented a non-primitive field and belonged to
  5.1025 -         * a non-local class descriptor.  To preserve this (questionable)
  5.1026 -         * behavior, the ObjectStreamField instances returned by matchFields
  5.1027 -         * cannot report non-primitive types other than Object.class; hence
  5.1028 -         * localFields cannot be returned directly.
  5.1029 -         */
  5.1030 -
  5.1031 -        ObjectStreamField[] matches = new ObjectStreamField[fields.length];
  5.1032 -        for (int i = 0; i < fields.length; i++) {
  5.1033 -            ObjectStreamField f = fields[i], m = null;
  5.1034 -            for (int j = 0; j < localFields.length; j++) {
  5.1035 -                ObjectStreamField lf = localFields[j];
  5.1036 -                if (f.getName().equals(lf.getName())) {
  5.1037 -                    if ((f.isPrimitive() || lf.isPrimitive()) &&
  5.1038 -                        f.getTypeCode() != lf.getTypeCode())
  5.1039 -                    {
  5.1040 -                        throw new InvalidClassException(localDesc.name,
  5.1041 -                            "incompatible types for field " + f.getName());
  5.1042 -                    }
  5.1043 -                    if (lf.getField() != null) {
  5.1044 -                        m = new ObjectStreamField(
  5.1045 -                            lf.getField(), lf.isUnshared(), false);
  5.1046 -                    } else {
  5.1047 -                        m = new ObjectStreamField(
  5.1048 -                            lf.getName(), lf.getSignature(), lf.isUnshared());
  5.1049 -                    }
  5.1050 -                }
  5.1051 -            }
  5.1052 -            if (m == null) {
  5.1053 -                m = new ObjectStreamField(
  5.1054 -                    f.getName(), f.getSignature(), false);
  5.1055 -            }
  5.1056 -            m.setOffset(f.getOffset());
  5.1057 -            matches[i] = m;
  5.1058 -        }
  5.1059 -        return matches;
  5.1060 -    }
  5.1061 -
  5.1062 -    /**
  5.1063 -     * Removes from the specified map any keys that have been enqueued
  5.1064 -     * on the specified reference queue.
  5.1065 -     */
  5.1066 -    static void processQueue(ReferenceQueue<Class<?>> queue,
  5.1067 -                             ConcurrentMap<? extends
  5.1068 -                             WeakReference<Class<?>>, ?> map)
  5.1069 -    {
  5.1070 -        Reference<? extends Class<?>> ref;
  5.1071 -        while((ref = queue.poll()) != null) {
  5.1072 -            map.remove(ref);
  5.1073 -        }
  5.1074 -    }
  5.1075 -
  5.1076 -    /**
  5.1077 -     *  Weak key for Class objects.
  5.1078 -     *
  5.1079 -     **/
  5.1080 -    static class WeakClassKey extends WeakReference<Class<?>> {
  5.1081 -        /**
  5.1082 -         * saved value of the referent's identity hash code, to maintain
  5.1083 -         * a consistent hash code after the referent has been cleared
  5.1084 -         */
  5.1085 -        private final int hash;
  5.1086 -
  5.1087 -        /**
  5.1088 -         * Create a new WeakClassKey to the given object, registered
  5.1089 -         * with a queue.
  5.1090 -         */
  5.1091 -        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
  5.1092 -            super(cl, refQueue);
  5.1093 -            hash = System.identityHashCode(cl);
  5.1094 -        }
  5.1095 -
  5.1096 -        /**
  5.1097 -         * Returns the identity hash code of the original referent.
  5.1098 -         */
  5.1099 -        public int hashCode() {
  5.1100 -            return hash;
  5.1101 -        }
  5.1102 -
  5.1103 -        /**
  5.1104 -         * Returns true if the given object is this identical
  5.1105 -         * WeakClassKey instance, or, if this object's referent has not
  5.1106 -         * been cleared, if the given object is another WeakClassKey
  5.1107 -         * instance with the identical non-null referent as this one.
  5.1108 -         */
  5.1109 -        public boolean equals(Object obj) {
  5.1110 -            if (obj == this) {
  5.1111 -                return true;
  5.1112 -            }
  5.1113 -
  5.1114 -            if (obj instanceof WeakClassKey) {
  5.1115 -                Object referent = get();
  5.1116 -                return (referent != null) &&
  5.1117 -                       (referent == ((WeakClassKey) obj).get());
  5.1118 -            } else {
  5.1119 -                return false;
  5.1120 -            }
  5.1121 -        }
  5.1122 -    }
  5.1123  }
     6.1 --- a/emul/compact/src/main/java/java/io/ObjectStreamConstants.java	Mon Jan 28 18:14:14 2013 +0100
     6.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamConstants.java	Mon Jan 28 18:15:21 2013 +0100
     6.3 @@ -179,26 +179,6 @@
     6.4      /* *******************************************************************/
     6.5      /* Security permissions */
     6.6  
     6.7 -    /**
     6.8 -     * Enable substitution of one object for another during
     6.9 -     * serialization/deserialization.
    6.10 -     *
    6.11 -     * @see java.io.ObjectOutputStream#enableReplaceObject(boolean)
    6.12 -     * @see java.io.ObjectInputStream#enableResolveObject(boolean)
    6.13 -     * @since 1.2
    6.14 -     */
    6.15 -    final static SerializablePermission SUBSTITUTION_PERMISSION =
    6.16 -                           new SerializablePermission("enableSubstitution");
    6.17 -
    6.18 -    /**
    6.19 -     * Enable overriding of readObject and writeObject.
    6.20 -     *
    6.21 -     * @see java.io.ObjectOutputStream#writeObjectOverride(Object)
    6.22 -     * @see java.io.ObjectInputStream#readObjectOverride()
    6.23 -     * @since 1.2
    6.24 -     */
    6.25 -    final static SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
    6.26 -                    new SerializablePermission("enableSubclassImplementation");
    6.27     /**
    6.28      * A Stream Protocol Version. <p>
    6.29      *
     7.1 --- a/emul/compact/src/main/java/java/lang/ref/Reference.java	Mon Jan 28 18:14:14 2013 +0100
     7.2 +++ b/emul/compact/src/main/java/java/lang/ref/Reference.java	Mon Jan 28 18:15:21 2013 +0100
     7.3 @@ -25,8 +25,6 @@
     7.4  
     7.5  package java.lang.ref;
     7.6  
     7.7 -import sun.misc.Cleaner;
     7.8 -
     7.9  
    7.10  /**
    7.11   * Abstract base class for reference objects.  This class defines the
    7.12 @@ -110,57 +108,6 @@
    7.13       */
    7.14      private static Reference pending = null;
    7.15  
    7.16 -    /* High-priority thread to enqueue pending References
    7.17 -     */
    7.18 -    private static class ReferenceHandler extends Thread {
    7.19 -
    7.20 -        ReferenceHandler(ThreadGroup g, String name) {
    7.21 -            super(g, name);
    7.22 -        }
    7.23 -
    7.24 -        public void run() {
    7.25 -            for (;;) {
    7.26 -
    7.27 -                Reference r;
    7.28 -                synchronized (lock) {
    7.29 -                    if (pending != null) {
    7.30 -                        r = pending;
    7.31 -                        Reference rn = r.next;
    7.32 -                        pending = (rn == r) ? null : rn;
    7.33 -                        r.next = r;
    7.34 -                    } else {
    7.35 -                        try {
    7.36 -                            lock.wait();
    7.37 -                        } catch (InterruptedException x) { }
    7.38 -                        continue;
    7.39 -                    }
    7.40 -                }
    7.41 -
    7.42 -                // Fast path for cleaners
    7.43 -                if (r instanceof Cleaner) {
    7.44 -                    ((Cleaner)r).clean();
    7.45 -                    continue;
    7.46 -                }
    7.47 -
    7.48 -                ReferenceQueue q = r.queue;
    7.49 -                if (q != ReferenceQueue.NULL) q.enqueue(r);
    7.50 -            }
    7.51 -        }
    7.52 -    }
    7.53 -
    7.54 -    static {
    7.55 -        ThreadGroup tg = Thread.currentThread().getThreadGroup();
    7.56 -        for (ThreadGroup tgn = tg;
    7.57 -             tgn != null;
    7.58 -             tg = tgn, tgn = tg.getParent());
    7.59 -        Thread handler = new ReferenceHandler(tg, "Reference Handler");
    7.60 -        /* If there were a special system-only priority greater than
    7.61 -         * MAX_PRIORITY, it would be used here
    7.62 -         */
    7.63 -        handler.setPriority(Thread.MAX_PRIORITY);
    7.64 -        handler.setDaemon(true);
    7.65 -        handler.start();
    7.66 -    }
    7.67  
    7.68  
    7.69      /* -- Referent accessor and setters -- */
     8.1 --- a/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java	Mon Jan 28 18:14:14 2013 +0100
     8.2 +++ b/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java	Mon Jan 28 18:15:21 2013 +0100
     8.3 @@ -62,9 +62,6 @@
     8.4                  r.next = (head == null) ? r : head;
     8.5                  head = r;
     8.6                  queueLength++;
     8.7 -                if (r instanceof FinalReference) {
     8.8 -                    sun.misc.VM.addFinalRefCount(1);
     8.9 -                }
    8.10                  lock.notifyAll();
    8.11                  return true;
    8.12              }
    8.13 @@ -78,9 +75,6 @@
    8.14              r.queue = NULL;
    8.15              r.next = r;
    8.16              queueLength--;
    8.17 -            if (r instanceof FinalReference) {
    8.18 -                sun.misc.VM.addFinalRefCount(-1);
    8.19 -            }
    8.20              return r;
    8.21          }
    8.22          return null;
     9.1 --- a/emul/mini/src/main/java/java/lang/Class.java	Mon Jan 28 18:14:14 2013 +0100
     9.2 +++ b/emul/mini/src/main/java/java/lang/Class.java	Mon Jan 28 18:15:21 2013 +0100
     9.3 @@ -909,7 +909,50 @@
     9.4          }
     9.5          return m;
     9.6      }
     9.7 -
     9.8 +    
     9.9 +    /**
    9.10 +     * Returns an array of {@code Method} objects reflecting all the
    9.11 +     * methods declared by the class or interface represented by this
    9.12 +     * {@code Class} object. This includes public, protected, default
    9.13 +     * (package) access, and private methods, but excludes inherited methods.
    9.14 +     * The elements in the array returned are not sorted and are not in any
    9.15 +     * particular order.  This method returns an array of length 0 if the class
    9.16 +     * or interface declares no methods, or if this {@code Class} object
    9.17 +     * represents a primitive type, an array class, or void.  The class
    9.18 +     * initialization method {@code <clinit>} is not included in the
    9.19 +     * returned array. If the class declares multiple public member methods
    9.20 +     * with the same parameter types, they are all included in the returned
    9.21 +     * array.
    9.22 +     *
    9.23 +     * <p> See <em>The Java Language Specification</em>, section 8.2.
    9.24 +     *
    9.25 +     * @return    the array of {@code Method} objects representing all the
    9.26 +     * declared methods of this class
    9.27 +     * @exception  SecurityException
    9.28 +     *             If a security manager, <i>s</i>, is present and any of the
    9.29 +     *             following conditions is met:
    9.30 +     *
    9.31 +     *             <ul>
    9.32 +     *
    9.33 +     *             <li> invocation of
    9.34 +     *             {@link SecurityManager#checkMemberAccess
    9.35 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
    9.36 +     *             access to the declared methods within this class
    9.37 +     *
    9.38 +     *             <li> the caller's class loader is not the same as or an
    9.39 +     *             ancestor of the class loader for the current class and
    9.40 +     *             invocation of {@link SecurityManager#checkPackageAccess
    9.41 +     *             s.checkPackageAccess()} denies access to the package
    9.42 +     *             of this class
    9.43 +     *
    9.44 +     *             </ul>
    9.45 +     *
    9.46 +     * @since JDK1.1
    9.47 +     */
    9.48 +    public Method[] getDeclaredMethods() throws SecurityException {
    9.49 +        throw new SecurityException();
    9.50 +    }
    9.51 +    
    9.52      /**
    9.53       * Character.isDigit answers {@code true} to some non-ascii
    9.54       * digits.  This one does not.
    9.55 @@ -1096,6 +1139,48 @@
    9.56      public ClassLoader getClassLoader() {
    9.57          throw new SecurityException();
    9.58      }
    9.59 +
    9.60 +    /**
    9.61 +     * Determines the interfaces implemented by the class or interface
    9.62 +     * represented by this object.
    9.63 +     *
    9.64 +     * <p> If this object represents a class, the return value is an array
    9.65 +     * containing objects representing all interfaces implemented by the
    9.66 +     * class. The order of the interface objects in the array corresponds to
    9.67 +     * the order of the interface names in the {@code implements} clause
    9.68 +     * of the declaration of the class represented by this object. For
    9.69 +     * example, given the declaration:
    9.70 +     * <blockquote>
    9.71 +     * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
    9.72 +     * </blockquote>
    9.73 +     * suppose the value of {@code s} is an instance of
    9.74 +     * {@code Shimmer}; the value of the expression:
    9.75 +     * <blockquote>
    9.76 +     * {@code s.getClass().getInterfaces()[0]}
    9.77 +     * </blockquote>
    9.78 +     * is the {@code Class} object that represents interface
    9.79 +     * {@code FloorWax}; and the value of:
    9.80 +     * <blockquote>
    9.81 +     * {@code s.getClass().getInterfaces()[1]}
    9.82 +     * </blockquote>
    9.83 +     * is the {@code Class} object that represents interface
    9.84 +     * {@code DessertTopping}.
    9.85 +     *
    9.86 +     * <p> If this object represents an interface, the array contains objects
    9.87 +     * representing all interfaces extended by the interface. The order of the
    9.88 +     * interface objects in the array corresponds to the order of the interface
    9.89 +     * names in the {@code extends} clause of the declaration of the
    9.90 +     * interface represented by this object.
    9.91 +     *
    9.92 +     * <p> If this object represents a class or interface that implements no
    9.93 +     * interfaces, the method returns an array of length 0.
    9.94 +     *
    9.95 +     * <p> If this object represents a primitive type or void, the method
    9.96 +     * returns an array of length 0.
    9.97 +     *
    9.98 +     * @return an array of interfaces implemented by this class.
    9.99 +     */
   9.100 +    public native Class<?>[] getInterfaces();
   9.101      
   9.102      /**
   9.103       * Returns the {@code Class} representing the component type of an
    10.1 --- a/emul/mini/src/main/java/java/lang/reflect/Constructor.java	Mon Jan 28 18:14:14 2013 +0100
    10.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Constructor.java	Mon Jan 28 18:15:21 2013 +0100
    10.3 @@ -25,17 +25,8 @@
    10.4  
    10.5  package java.lang.reflect;
    10.6  
    10.7 -import sun.reflect.ConstructorAccessor;
    10.8 -import sun.reflect.Reflection;
    10.9 -import sun.reflect.generics.repository.ConstructorRepository;
   10.10 -import sun.reflect.generics.factory.CoreReflectionFactory;
   10.11 -import sun.reflect.generics.factory.GenericsFactory;
   10.12 -import sun.reflect.generics.scope.ConstructorScope;
   10.13  import java.lang.annotation.Annotation;
   10.14 -import java.util.Map;
   10.15 -import sun.reflect.annotation.AnnotationParser;
   10.16 -import java.lang.annotation.AnnotationFormatError;
   10.17 -import java.lang.reflect.Modifier;
   10.18 +import org.apidesign.bck2brwsr.emul.reflect.TypeProvider;
   10.19  
   10.20  /**
   10.21   * {@code Constructor} provides information about, and access to, a single
   10.22 @@ -69,31 +60,10 @@
   10.23      private int                 modifiers;
   10.24      // Generics and annotations support
   10.25      private transient String    signature;
   10.26 -    // generic info repository; lazily initialized
   10.27 -    private transient ConstructorRepository genericInfo;
   10.28      private byte[]              annotations;
   10.29      private byte[]              parameterAnnotations;
   10.30  
   10.31 -    // Generics infrastructure
   10.32 -    // Accessor for factory
   10.33 -    private GenericsFactory getFactory() {
   10.34 -        // create scope and factory
   10.35 -        return CoreReflectionFactory.make(this, ConstructorScope.make(this));
   10.36 -    }
   10.37  
   10.38 -    // Accessor for generic info repository
   10.39 -    private ConstructorRepository getGenericInfo() {
   10.40 -        // lazily initialize repository if necessary
   10.41 -        if (genericInfo == null) {
   10.42 -            // create and cache generic info repository
   10.43 -            genericInfo =
   10.44 -                ConstructorRepository.make(getSignature(),
   10.45 -                                           getFactory());
   10.46 -        }
   10.47 -        return genericInfo; //return cached repository
   10.48 -    }
   10.49 -
   10.50 -    private volatile ConstructorAccessor constructorAccessor;
   10.51      // For sharing of ConstructorAccessors. This branching structure
   10.52      // is currently only two levels deep (i.e., one root Constructor
   10.53      // and potentially many Constructor objects pointing to it.)
   10.54 @@ -129,23 +99,7 @@
   10.55       * "root" field points to this Constructor.
   10.56       */
   10.57      Constructor<T> copy() {
   10.58 -        // This routine enables sharing of ConstructorAccessor objects
   10.59 -        // among Constructor objects which refer to the same underlying
   10.60 -        // method in the VM. (All of this contortion is only necessary
   10.61 -        // because of the "accessibility" bit in AccessibleObject,
   10.62 -        // which implicitly requires that new java.lang.reflect
   10.63 -        // objects be fabricated for each reflective call on Class
   10.64 -        // objects.)
   10.65 -        Constructor<T> res = new Constructor<>(clazz,
   10.66 -                                                parameterTypes,
   10.67 -                                                exceptionTypes, modifiers, slot,
   10.68 -                                                signature,
   10.69 -                                                annotations,
   10.70 -                                                parameterAnnotations);
   10.71 -        res.root = this;
   10.72 -        // Might as well eagerly propagate this if already present
   10.73 -        res.constructorAccessor = constructorAccessor;
   10.74 -        return res;
   10.75 +        return this;
   10.76      }
   10.77  
   10.78      /**
   10.79 @@ -191,10 +145,7 @@
   10.80       * @since 1.5
   10.81       */
   10.82      public TypeVariable<Constructor<T>>[] getTypeParameters() {
   10.83 -      if (getSignature() != null) {
   10.84 -        return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();
   10.85 -      } else
   10.86 -          return (TypeVariable<Constructor<T>>[])new TypeVariable[0];
   10.87 +        return TypeProvider.getDefault().getTypeParameters(this);
   10.88      }
   10.89  
   10.90  
   10.91 @@ -240,10 +191,7 @@
   10.92       * @since 1.5
   10.93       */
   10.94      public Type[] getGenericParameterTypes() {
   10.95 -        if (getSignature() != null)
   10.96 -            return getGenericInfo().getParameterTypes();
   10.97 -        else
   10.98 -            return getParameterTypes();
   10.99 +        return TypeProvider.getDefault().getGenericParameterTypes(this);
  10.100      }
  10.101  
  10.102  
  10.103 @@ -284,12 +232,7 @@
  10.104       * @since 1.5
  10.105       */
  10.106        public Type[] getGenericExceptionTypes() {
  10.107 -          Type[] result;
  10.108 -          if (getSignature() != null &&
  10.109 -              ( (result = getGenericInfo().getExceptionTypes()).length > 0  ))
  10.110 -              return result;
  10.111 -          else
  10.112 -              return getExceptionTypes();
  10.113 +          return TypeProvider.getDefault().getGenericExceptionTypes(this);
  10.114        }
  10.115  
  10.116      /**
  10.117 @@ -509,20 +452,7 @@
  10.118          throws InstantiationException, IllegalAccessException,
  10.119                 IllegalArgumentException, InvocationTargetException
  10.120      {
  10.121 -        if (!override) {
  10.122 -            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  10.123 -                Class<?> caller = Reflection.getCallerClass(2);
  10.124 -
  10.125 -                checkAccess(caller, clazz, null, modifiers);
  10.126 -            }
  10.127 -        }
  10.128 -        if ((clazz.getModifiers() & Modifier.ENUM) != 0)
  10.129 -            throw new IllegalArgumentException("Cannot reflectively create enum objects");
  10.130 -        ConstructorAccessor ca = constructorAccessor;   // read volatile
  10.131 -        if (ca == null) {
  10.132 -            ca = acquireConstructorAccessor();
  10.133 -        }
  10.134 -        return (T) ca.newInstance(initargs);
  10.135 +        throw new SecurityException();
  10.136      }
  10.137  
  10.138      /**
  10.139 @@ -551,43 +481,6 @@
  10.140          return Modifier.isSynthetic(getModifiers());
  10.141      }
  10.142  
  10.143 -    // NOTE that there is no synchronization used here. It is correct
  10.144 -    // (though not efficient) to generate more than one
  10.145 -    // ConstructorAccessor for a given Constructor. However, avoiding
  10.146 -    // synchronization will probably make the implementation more
  10.147 -    // scalable.
  10.148 -    private ConstructorAccessor acquireConstructorAccessor() {
  10.149 -        // First check to see if one has been created yet, and take it
  10.150 -        // if so.
  10.151 -        ConstructorAccessor tmp = null;
  10.152 -        if (root != null) tmp = root.getConstructorAccessor();
  10.153 -        if (tmp != null) {
  10.154 -            constructorAccessor = tmp;
  10.155 -        } else {
  10.156 -            // Otherwise fabricate one and propagate it up to the root
  10.157 -            tmp = reflectionFactory.newConstructorAccessor(this);
  10.158 -            setConstructorAccessor(tmp);
  10.159 -        }
  10.160 -
  10.161 -        return tmp;
  10.162 -    }
  10.163 -
  10.164 -    // Returns ConstructorAccessor for this Constructor object, not
  10.165 -    // looking up the chain to the root
  10.166 -    ConstructorAccessor getConstructorAccessor() {
  10.167 -        return constructorAccessor;
  10.168 -    }
  10.169 -
  10.170 -    // Sets the ConstructorAccessor for this Constructor object and
  10.171 -    // (recursively) its root
  10.172 -    void setConstructorAccessor(ConstructorAccessor accessor) {
  10.173 -        constructorAccessor = accessor;
  10.174 -        // Propagate up
  10.175 -        if (root != null) {
  10.176 -            root.setConstructorAccessor(accessor);
  10.177 -        }
  10.178 -    }
  10.179 -
  10.180      int getSlot() {
  10.181          return slot;
  10.182      }
  10.183 @@ -612,26 +505,14 @@
  10.184          if (annotationClass == null)
  10.185              throw new NullPointerException();
  10.186  
  10.187 -        return (T) declaredAnnotations().get(annotationClass);
  10.188 +        return null; // XXX (T) declaredAnnotations().get(annotationClass);
  10.189      }
  10.190  
  10.191      /**
  10.192       * @since 1.5
  10.193       */
  10.194      public Annotation[] getDeclaredAnnotations()  {
  10.195 -        return AnnotationParser.toArray(declaredAnnotations());
  10.196 -    }
  10.197 -
  10.198 -    private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
  10.199 -
  10.200 -    private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
  10.201 -        if (declaredAnnotations == null) {
  10.202 -            declaredAnnotations = AnnotationParser.parseAnnotations(
  10.203 -                annotations, sun.misc.SharedSecrets.getJavaLangAccess().
  10.204 -                getConstantPool(getDeclaringClass()),
  10.205 -                getDeclaringClass());
  10.206 -        }
  10.207 -        return declaredAnnotations;
  10.208 +        return new Annotation[0]; // XXX AnnotationParser.toArray(declaredAnnotations());
  10.209      }
  10.210  
  10.211      /**
  10.212 @@ -654,7 +535,9 @@
  10.213          int numParameters = parameterTypes.length;
  10.214          if (parameterAnnotations == null)
  10.215              return new Annotation[numParameters][0];
  10.216 -
  10.217 +        
  10.218 +        return new Annotation[numParameters][0]; // XXX
  10.219 +/*
  10.220          Annotation[][] result = AnnotationParser.parseParameterAnnotations(
  10.221              parameterAnnotations,
  10.222              sun.misc.SharedSecrets.getJavaLangAccess().
  10.223 @@ -679,5 +562,6 @@
  10.224              }
  10.225          }
  10.226          return result;
  10.227 +        */
  10.228      }
  10.229  }
    11.1 --- a/emul/mini/src/main/java/java/lang/reflect/Proxy.java	Mon Jan 28 18:14:14 2013 +0100
    11.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Proxy.java	Mon Jan 28 18:15:21 2013 +0100
    11.3 @@ -25,17 +25,6 @@
    11.4  
    11.5  package java.lang.reflect;
    11.6  
    11.7 -import java.lang.ref.Reference;
    11.8 -import java.lang.ref.WeakReference;
    11.9 -import java.util.Arrays;
   11.10 -import java.util.Collections;
   11.11 -import java.util.HashMap;
   11.12 -import java.util.HashSet;
   11.13 -import java.util.Map;
   11.14 -import java.util.Set;
   11.15 -import java.util.List;
   11.16 -import java.util.WeakHashMap;
   11.17 -import sun.misc.ProxyGenerator;
   11.18  
   11.19  /**
   11.20   * {@code Proxy} provides static methods for creating dynamic proxy
   11.21 @@ -223,27 +212,7 @@
   11.22  
   11.23      private static final long serialVersionUID = -2222568056686623797L;
   11.24  
   11.25 -    /** prefix for all proxy class names */
   11.26 -    private final static String proxyClassNamePrefix = "$Proxy";
   11.27  
   11.28 -    /** parameter types of a proxy class constructor */
   11.29 -    private final static Class[] constructorParams =
   11.30 -        { InvocationHandler.class };
   11.31 -
   11.32 -    /** maps a class loader to the proxy class cache for that loader */
   11.33 -    private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache
   11.34 -        = new WeakHashMap<>();
   11.35 -
   11.36 -    /** marks that a particular proxy class is currently being generated */
   11.37 -    private static Object pendingGenerationMarker = new Object();
   11.38 -
   11.39 -    /** next number to use for generation of unique proxy class names */
   11.40 -    private static long nextUniqueNumber = 0;
   11.41 -    private static Object nextUniqueNumberLock = new Object();
   11.42 -
   11.43 -    /** set of all generated proxy classes, for isProxyClass implementation */
   11.44 -    private static Map<Class<?>, Void> proxyClasses =
   11.45 -        Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());
   11.46  
   11.47      /**
   11.48       * the invocation handler for this proxy instance.
   11.49 @@ -346,215 +315,7 @@
   11.50                                           Class<?>... interfaces)
   11.51          throws IllegalArgumentException
   11.52      {
   11.53 -        if (interfaces.length > 65535) {
   11.54 -            throw new IllegalArgumentException("interface limit exceeded");
   11.55 -        }
   11.56 -
   11.57 -        Class<?> proxyClass = null;
   11.58 -
   11.59 -        /* collect interface names to use as key for proxy class cache */
   11.60 -        String[] interfaceNames = new String[interfaces.length];
   11.61 -
   11.62 -        // for detecting duplicates
   11.63 -        Set<Class<?>> interfaceSet = new HashSet<>();
   11.64 -
   11.65 -        for (int i = 0; i < interfaces.length; i++) {
   11.66 -            /*
   11.67 -             * Verify that the class loader resolves the name of this
   11.68 -             * interface to the same Class object.
   11.69 -             */
   11.70 -            String interfaceName = interfaces[i].getName();
   11.71 -            Class<?> interfaceClass = null;
   11.72 -            try {
   11.73 -                interfaceClass = Class.forName(interfaceName, false, loader);
   11.74 -            } catch (ClassNotFoundException e) {
   11.75 -            }
   11.76 -            if (interfaceClass != interfaces[i]) {
   11.77 -                throw new IllegalArgumentException(
   11.78 -                    interfaces[i] + " is not visible from class loader");
   11.79 -            }
   11.80 -
   11.81 -            /*
   11.82 -             * Verify that the Class object actually represents an
   11.83 -             * interface.
   11.84 -             */
   11.85 -            if (!interfaceClass.isInterface()) {
   11.86 -                throw new IllegalArgumentException(
   11.87 -                    interfaceClass.getName() + " is not an interface");
   11.88 -            }
   11.89 -
   11.90 -            /*
   11.91 -             * Verify that this interface is not a duplicate.
   11.92 -             */
   11.93 -            if (interfaceSet.contains(interfaceClass)) {
   11.94 -                throw new IllegalArgumentException(
   11.95 -                    "repeated interface: " + interfaceClass.getName());
   11.96 -            }
   11.97 -            interfaceSet.add(interfaceClass);
   11.98 -
   11.99 -            interfaceNames[i] = interfaceName;
  11.100 -        }
  11.101 -
  11.102 -        /*
  11.103 -         * Using string representations of the proxy interfaces as
  11.104 -         * keys in the proxy class cache (instead of their Class
  11.105 -         * objects) is sufficient because we require the proxy
  11.106 -         * interfaces to be resolvable by name through the supplied
  11.107 -         * class loader, and it has the advantage that using a string
  11.108 -         * representation of a class makes for an implicit weak
  11.109 -         * reference to the class.
  11.110 -         */
  11.111 -        List<String> key = Arrays.asList(interfaceNames);
  11.112 -
  11.113 -        /*
  11.114 -         * Find or create the proxy class cache for the class loader.
  11.115 -         */
  11.116 -        Map<List<String>, Object> cache;
  11.117 -        synchronized (loaderToCache) {
  11.118 -            cache = loaderToCache.get(loader);
  11.119 -            if (cache == null) {
  11.120 -                cache = new HashMap<>();
  11.121 -                loaderToCache.put(loader, cache);
  11.122 -            }
  11.123 -            /*
  11.124 -             * This mapping will remain valid for the duration of this
  11.125 -             * method, without further synchronization, because the mapping
  11.126 -             * will only be removed if the class loader becomes unreachable.
  11.127 -             */
  11.128 -        }
  11.129 -
  11.130 -        /*
  11.131 -         * Look up the list of interfaces in the proxy class cache using
  11.132 -         * the key.  This lookup will result in one of three possible
  11.133 -         * kinds of values:
  11.134 -         *     null, if there is currently no proxy class for the list of
  11.135 -         *         interfaces in the class loader,
  11.136 -         *     the pendingGenerationMarker object, if a proxy class for the
  11.137 -         *         list of interfaces is currently being generated,
  11.138 -         *     or a weak reference to a Class object, if a proxy class for
  11.139 -         *         the list of interfaces has already been generated.
  11.140 -         */
  11.141 -        synchronized (cache) {
  11.142 -            /*
  11.143 -             * Note that we need not worry about reaping the cache for
  11.144 -             * entries with cleared weak references because if a proxy class
  11.145 -             * has been garbage collected, its class loader will have been
  11.146 -             * garbage collected as well, so the entire cache will be reaped
  11.147 -             * from the loaderToCache map.
  11.148 -             */
  11.149 -            do {
  11.150 -                Object value = cache.get(key);
  11.151 -                if (value instanceof Reference) {
  11.152 -                    proxyClass = (Class<?>) ((Reference) value).get();
  11.153 -                }
  11.154 -                if (proxyClass != null) {
  11.155 -                    // proxy class already generated: return it
  11.156 -                    return proxyClass;
  11.157 -                } else if (value == pendingGenerationMarker) {
  11.158 -                    // proxy class being generated: wait for it
  11.159 -                    try {
  11.160 -                        cache.wait();
  11.161 -                    } catch (InterruptedException e) {
  11.162 -                        /*
  11.163 -                         * The class generation that we are waiting for should
  11.164 -                         * take a small, bounded time, so we can safely ignore
  11.165 -                         * thread interrupts here.
  11.166 -                         */
  11.167 -                    }
  11.168 -                    continue;
  11.169 -                } else {
  11.170 -                    /*
  11.171 -                     * No proxy class for this list of interfaces has been
  11.172 -                     * generated or is being generated, so we will go and
  11.173 -                     * generate it now.  Mark it as pending generation.
  11.174 -                     */
  11.175 -                    cache.put(key, pendingGenerationMarker);
  11.176 -                    break;
  11.177 -                }
  11.178 -            } while (true);
  11.179 -        }
  11.180 -
  11.181 -        try {
  11.182 -            String proxyPkg = null;     // package to define proxy class in
  11.183 -
  11.184 -            /*
  11.185 -             * Record the package of a non-public proxy interface so that the
  11.186 -             * proxy class will be defined in the same package.  Verify that
  11.187 -             * all non-public proxy interfaces are in the same package.
  11.188 -             */
  11.189 -            for (int i = 0; i < interfaces.length; i++) {
  11.190 -                int flags = interfaces[i].getModifiers();
  11.191 -                if (!Modifier.isPublic(flags)) {
  11.192 -                    String name = interfaces[i].getName();
  11.193 -                    int n = name.lastIndexOf('.');
  11.194 -                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
  11.195 -                    if (proxyPkg == null) {
  11.196 -                        proxyPkg = pkg;
  11.197 -                    } else if (!pkg.equals(proxyPkg)) {
  11.198 -                        throw new IllegalArgumentException(
  11.199 -                            "non-public interfaces from different packages");
  11.200 -                    }
  11.201 -                }
  11.202 -            }
  11.203 -
  11.204 -            if (proxyPkg == null) {     // if no non-public proxy interfaces,
  11.205 -                proxyPkg = "";          // use the unnamed package
  11.206 -            }
  11.207 -
  11.208 -            {
  11.209 -                /*
  11.210 -                 * Choose a name for the proxy class to generate.
  11.211 -                 */
  11.212 -                long num;
  11.213 -                synchronized (nextUniqueNumberLock) {
  11.214 -                    num = nextUniqueNumber++;
  11.215 -                }
  11.216 -                String proxyName = proxyPkg + proxyClassNamePrefix + num;
  11.217 -                /*
  11.218 -                 * Verify that the class loader hasn't already
  11.219 -                 * defined a class with the chosen name.
  11.220 -                 */
  11.221 -
  11.222 -                /*
  11.223 -                 * Generate the specified proxy class.
  11.224 -                 */
  11.225 -                byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
  11.226 -                    proxyName, interfaces);
  11.227 -                try {
  11.228 -                    proxyClass = defineClass0(loader, proxyName,
  11.229 -                        proxyClassFile, 0, proxyClassFile.length);
  11.230 -                } catch (ClassFormatError e) {
  11.231 -                    /*
  11.232 -                     * A ClassFormatError here means that (barring bugs in the
  11.233 -                     * proxy class generation code) there was some other
  11.234 -                     * invalid aspect of the arguments supplied to the proxy
  11.235 -                     * class creation (such as virtual machine limitations
  11.236 -                     * exceeded).
  11.237 -                     */
  11.238 -                    throw new IllegalArgumentException(e.toString());
  11.239 -                }
  11.240 -            }
  11.241 -            // add to set of all generated proxy classes, for isProxyClass
  11.242 -            proxyClasses.put(proxyClass, null);
  11.243 -
  11.244 -        } finally {
  11.245 -            /*
  11.246 -             * We must clean up the "pending generation" state of the proxy
  11.247 -             * class cache entry somehow.  If a proxy class was successfully
  11.248 -             * generated, store it in the cache (with a weak reference);
  11.249 -             * otherwise, remove the reserved entry.  In all cases, notify
  11.250 -             * all waiters on reserved entries in this cache.
  11.251 -             */
  11.252 -            synchronized (cache) {
  11.253 -                if (proxyClass != null) {
  11.254 -                    cache.put(key, new WeakReference<Class<?>>(proxyClass));
  11.255 -                } else {
  11.256 -                    cache.remove(key);
  11.257 -                }
  11.258 -                cache.notifyAll();
  11.259 -            }
  11.260 -        }
  11.261 -        return proxyClass;
  11.262 +        throw new IllegalArgumentException();
  11.263      }
  11.264  
  11.265      /**
  11.266 @@ -594,27 +355,7 @@
  11.267          if (h == null) {
  11.268              throw new NullPointerException();
  11.269          }
  11.270 -
  11.271 -        /*
  11.272 -         * Look up or generate the designated proxy class.
  11.273 -         */
  11.274 -        Class<?> cl = getProxyClass(loader, interfaces);
  11.275 -
  11.276 -        /*
  11.277 -         * Invoke its constructor with the designated invocation handler.
  11.278 -         */
  11.279 -        try {
  11.280 -            Constructor cons = cl.getConstructor(constructorParams);
  11.281 -            return cons.newInstance(new Object[] { h });
  11.282 -        } catch (NoSuchMethodException e) {
  11.283 -            throw new InternalError(e.toString());
  11.284 -        } catch (IllegalAccessException e) {
  11.285 -            throw new InternalError(e.toString());
  11.286 -        } catch (InstantiationException e) {
  11.287 -            throw new InternalError(e.toString());
  11.288 -        } catch (InvocationTargetException e) {
  11.289 -            throw new InternalError(e.toString());
  11.290 -        }
  11.291 +        throw new IllegalArgumentException();
  11.292      }
  11.293  
  11.294      /**
  11.295 @@ -636,7 +377,7 @@
  11.296              throw new NullPointerException();
  11.297          }
  11.298  
  11.299 -        return proxyClasses.containsKey(cl);
  11.300 +        return false;
  11.301      }
  11.302  
  11.303      /**
    12.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java	Mon Jan 28 18:14:14 2013 +0100
    12.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java	Mon Jan 28 18:15:21 2013 +0100
    12.3 @@ -47,4 +47,8 @@
    12.4  
    12.5      @JavaScriptBody(args = {}, body = "new Date().getMilliseconds() * 1000;")
    12.6      public static native long nanoTime();
    12.7 +    
    12.8 +    @JavaScriptBody(args = { "obj" }, body="return vm.java_lang_Object(false).hashCode__I.call(obj);")
    12.9 +    public static native int identityHashCode(Object obj);
   12.10 +    
   12.11  }
    13.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Mon Jan 28 18:14:14 2013 +0100
    13.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Mon Jan 28 18:15:21 2013 +0100
    13.3 @@ -1,26 +1,19 @@
    13.4 -/*
    13.5 - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    13.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 +/**
    13.8 + * Back 2 Browser Bytecode Translator
    13.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   13.10   *
   13.11 - * This code is free software; you can redistribute it and/or modify it
   13.12 - * under the terms of the GNU General Public License version 2 only, as
   13.13 - * published by the Free Software Foundation.  Oracle designates this
   13.14 - * particular file as subject to the "Classpath" exception as provided
   13.15 - * by Oracle in the LICENSE file that accompanied this code.
   13.16 + * This program is free software: you can redistribute it and/or modify
   13.17 + * it under the terms of the GNU General Public License as published by
   13.18 + * the Free Software Foundation, version 2 of the License.
   13.19   *
   13.20 - * This code is distributed in the hope that it will be useful, but WITHOUT
   13.21 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.22 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.23 - * version 2 for more details (a copy is included in the LICENSE file that
   13.24 - * accompanied this code).
   13.25 + * This program is distributed in the hope that it will be useful,
   13.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.28 + * GNU General Public License for more details.
   13.29   *
   13.30 - * You should have received a copy of the GNU General Public License version
   13.31 - * 2 along with this work; if not, write to the Free Software Foundation,
   13.32 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.33 - *
   13.34 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.35 - * or visit www.oracle.com if you need additional information or have any
   13.36 - * questions.
   13.37 + * You should have received a copy of the GNU General Public License
   13.38 + * along with this program. Look for COPYING file in the top folder.
   13.39 + * If not, see http://opensource.org/licenses/GPL-2.0.
   13.40   */
   13.41  package org.apidesign.bck2brwsr.emul.reflect;
   13.42  
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/TypeProvider.java	Mon Jan 28 18:15:21 2013 +0100
    14.3 @@ -0,0 +1,40 @@
    14.4 +/**
    14.5 + * Back 2 Browser Bytecode Translator
    14.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    14.7 + *
    14.8 + * This program is free software: you can redistribute it and/or modify
    14.9 + * it under the terms of the GNU General Public License as published by
   14.10 + * the Free Software Foundation, version 2 of the License.
   14.11 + *
   14.12 + * This program is distributed in the hope that it will be useful,
   14.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.15 + * GNU General Public License for more details.
   14.16 + *
   14.17 + * You should have received a copy of the GNU General Public License
   14.18 + * along with this program. Look for COPYING file in the top folder.
   14.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   14.20 + */
   14.21 +package org.apidesign.bck2brwsr.emul.reflect;
   14.22 +
   14.23 +import java.lang.reflect.Constructor;
   14.24 +import java.lang.reflect.Type;
   14.25 +import java.lang.reflect.TypeVariable;
   14.26 +
   14.27 +/**
   14.28 + *
   14.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   14.30 + */
   14.31 +public abstract class TypeProvider {
   14.32 +    private TypeProvider() {
   14.33 +    }
   14.34 +    
   14.35 +    public static TypeProvider getDefault() {
   14.36 +        return null;
   14.37 +    }
   14.38 +    
   14.39 +    public abstract <T> TypeVariable<Constructor<T>>[] getTypeParameters(Constructor<T> c);
   14.40 +    public abstract <T> Type[] getGenericParameterTypes(Constructor<T> c);
   14.41 +    public abstract <T> Type[] getGenericExceptionTypes(Constructor<T> c);
   14.42 +    
   14.43 +}