1.1 --- a/emul/mini/src/main/java/java/lang/reflect/Proxy.java Mon Jan 28 18:12:47 2013 +0100
1.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Proxy.java Mon Jan 28 18:15:21 2013 +0100
1.3 @@ -25,17 +25,6 @@
1.4
1.5 package java.lang.reflect;
1.6
1.7 -import java.lang.ref.Reference;
1.8 -import java.lang.ref.WeakReference;
1.9 -import java.util.Arrays;
1.10 -import java.util.Collections;
1.11 -import java.util.HashMap;
1.12 -import java.util.HashSet;
1.13 -import java.util.Map;
1.14 -import java.util.Set;
1.15 -import java.util.List;
1.16 -import java.util.WeakHashMap;
1.17 -import sun.misc.ProxyGenerator;
1.18
1.19 /**
1.20 * {@code Proxy} provides static methods for creating dynamic proxy
1.21 @@ -223,27 +212,7 @@
1.22
1.23 private static final long serialVersionUID = -2222568056686623797L;
1.24
1.25 - /** prefix for all proxy class names */
1.26 - private final static String proxyClassNamePrefix = "$Proxy";
1.27
1.28 - /** parameter types of a proxy class constructor */
1.29 - private final static Class[] constructorParams =
1.30 - { InvocationHandler.class };
1.31 -
1.32 - /** maps a class loader to the proxy class cache for that loader */
1.33 - private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache
1.34 - = new WeakHashMap<>();
1.35 -
1.36 - /** marks that a particular proxy class is currently being generated */
1.37 - private static Object pendingGenerationMarker = new Object();
1.38 -
1.39 - /** next number to use for generation of unique proxy class names */
1.40 - private static long nextUniqueNumber = 0;
1.41 - private static Object nextUniqueNumberLock = new Object();
1.42 -
1.43 - /** set of all generated proxy classes, for isProxyClass implementation */
1.44 - private static Map<Class<?>, Void> proxyClasses =
1.45 - Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());
1.46
1.47 /**
1.48 * the invocation handler for this proxy instance.
1.49 @@ -346,215 +315,7 @@
1.50 Class<?>... interfaces)
1.51 throws IllegalArgumentException
1.52 {
1.53 - if (interfaces.length > 65535) {
1.54 - throw new IllegalArgumentException("interface limit exceeded");
1.55 - }
1.56 -
1.57 - Class<?> proxyClass = null;
1.58 -
1.59 - /* collect interface names to use as key for proxy class cache */
1.60 - String[] interfaceNames = new String[interfaces.length];
1.61 -
1.62 - // for detecting duplicates
1.63 - Set<Class<?>> interfaceSet = new HashSet<>();
1.64 -
1.65 - for (int i = 0; i < interfaces.length; i++) {
1.66 - /*
1.67 - * Verify that the class loader resolves the name of this
1.68 - * interface to the same Class object.
1.69 - */
1.70 - String interfaceName = interfaces[i].getName();
1.71 - Class<?> interfaceClass = null;
1.72 - try {
1.73 - interfaceClass = Class.forName(interfaceName, false, loader);
1.74 - } catch (ClassNotFoundException e) {
1.75 - }
1.76 - if (interfaceClass != interfaces[i]) {
1.77 - throw new IllegalArgumentException(
1.78 - interfaces[i] + " is not visible from class loader");
1.79 - }
1.80 -
1.81 - /*
1.82 - * Verify that the Class object actually represents an
1.83 - * interface.
1.84 - */
1.85 - if (!interfaceClass.isInterface()) {
1.86 - throw new IllegalArgumentException(
1.87 - interfaceClass.getName() + " is not an interface");
1.88 - }
1.89 -
1.90 - /*
1.91 - * Verify that this interface is not a duplicate.
1.92 - */
1.93 - if (interfaceSet.contains(interfaceClass)) {
1.94 - throw new IllegalArgumentException(
1.95 - "repeated interface: " + interfaceClass.getName());
1.96 - }
1.97 - interfaceSet.add(interfaceClass);
1.98 -
1.99 - interfaceNames[i] = interfaceName;
1.100 - }
1.101 -
1.102 - /*
1.103 - * Using string representations of the proxy interfaces as
1.104 - * keys in the proxy class cache (instead of their Class
1.105 - * objects) is sufficient because we require the proxy
1.106 - * interfaces to be resolvable by name through the supplied
1.107 - * class loader, and it has the advantage that using a string
1.108 - * representation of a class makes for an implicit weak
1.109 - * reference to the class.
1.110 - */
1.111 - List<String> key = Arrays.asList(interfaceNames);
1.112 -
1.113 - /*
1.114 - * Find or create the proxy class cache for the class loader.
1.115 - */
1.116 - Map<List<String>, Object> cache;
1.117 - synchronized (loaderToCache) {
1.118 - cache = loaderToCache.get(loader);
1.119 - if (cache == null) {
1.120 - cache = new HashMap<>();
1.121 - loaderToCache.put(loader, cache);
1.122 - }
1.123 - /*
1.124 - * This mapping will remain valid for the duration of this
1.125 - * method, without further synchronization, because the mapping
1.126 - * will only be removed if the class loader becomes unreachable.
1.127 - */
1.128 - }
1.129 -
1.130 - /*
1.131 - * Look up the list of interfaces in the proxy class cache using
1.132 - * the key. This lookup will result in one of three possible
1.133 - * kinds of values:
1.134 - * null, if there is currently no proxy class for the list of
1.135 - * interfaces in the class loader,
1.136 - * the pendingGenerationMarker object, if a proxy class for the
1.137 - * list of interfaces is currently being generated,
1.138 - * or a weak reference to a Class object, if a proxy class for
1.139 - * the list of interfaces has already been generated.
1.140 - */
1.141 - synchronized (cache) {
1.142 - /*
1.143 - * Note that we need not worry about reaping the cache for
1.144 - * entries with cleared weak references because if a proxy class
1.145 - * has been garbage collected, its class loader will have been
1.146 - * garbage collected as well, so the entire cache will be reaped
1.147 - * from the loaderToCache map.
1.148 - */
1.149 - do {
1.150 - Object value = cache.get(key);
1.151 - if (value instanceof Reference) {
1.152 - proxyClass = (Class<?>) ((Reference) value).get();
1.153 - }
1.154 - if (proxyClass != null) {
1.155 - // proxy class already generated: return it
1.156 - return proxyClass;
1.157 - } else if (value == pendingGenerationMarker) {
1.158 - // proxy class being generated: wait for it
1.159 - try {
1.160 - cache.wait();
1.161 - } catch (InterruptedException e) {
1.162 - /*
1.163 - * The class generation that we are waiting for should
1.164 - * take a small, bounded time, so we can safely ignore
1.165 - * thread interrupts here.
1.166 - */
1.167 - }
1.168 - continue;
1.169 - } else {
1.170 - /*
1.171 - * No proxy class for this list of interfaces has been
1.172 - * generated or is being generated, so we will go and
1.173 - * generate it now. Mark it as pending generation.
1.174 - */
1.175 - cache.put(key, pendingGenerationMarker);
1.176 - break;
1.177 - }
1.178 - } while (true);
1.179 - }
1.180 -
1.181 - try {
1.182 - String proxyPkg = null; // package to define proxy class in
1.183 -
1.184 - /*
1.185 - * Record the package of a non-public proxy interface so that the
1.186 - * proxy class will be defined in the same package. Verify that
1.187 - * all non-public proxy interfaces are in the same package.
1.188 - */
1.189 - for (int i = 0; i < interfaces.length; i++) {
1.190 - int flags = interfaces[i].getModifiers();
1.191 - if (!Modifier.isPublic(flags)) {
1.192 - String name = interfaces[i].getName();
1.193 - int n = name.lastIndexOf('.');
1.194 - String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
1.195 - if (proxyPkg == null) {
1.196 - proxyPkg = pkg;
1.197 - } else if (!pkg.equals(proxyPkg)) {
1.198 - throw new IllegalArgumentException(
1.199 - "non-public interfaces from different packages");
1.200 - }
1.201 - }
1.202 - }
1.203 -
1.204 - if (proxyPkg == null) { // if no non-public proxy interfaces,
1.205 - proxyPkg = ""; // use the unnamed package
1.206 - }
1.207 -
1.208 - {
1.209 - /*
1.210 - * Choose a name for the proxy class to generate.
1.211 - */
1.212 - long num;
1.213 - synchronized (nextUniqueNumberLock) {
1.214 - num = nextUniqueNumber++;
1.215 - }
1.216 - String proxyName = proxyPkg + proxyClassNamePrefix + num;
1.217 - /*
1.218 - * Verify that the class loader hasn't already
1.219 - * defined a class with the chosen name.
1.220 - */
1.221 -
1.222 - /*
1.223 - * Generate the specified proxy class.
1.224 - */
1.225 - byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
1.226 - proxyName, interfaces);
1.227 - try {
1.228 - proxyClass = defineClass0(loader, proxyName,
1.229 - proxyClassFile, 0, proxyClassFile.length);
1.230 - } catch (ClassFormatError e) {
1.231 - /*
1.232 - * A ClassFormatError here means that (barring bugs in the
1.233 - * proxy class generation code) there was some other
1.234 - * invalid aspect of the arguments supplied to the proxy
1.235 - * class creation (such as virtual machine limitations
1.236 - * exceeded).
1.237 - */
1.238 - throw new IllegalArgumentException(e.toString());
1.239 - }
1.240 - }
1.241 - // add to set of all generated proxy classes, for isProxyClass
1.242 - proxyClasses.put(proxyClass, null);
1.243 -
1.244 - } finally {
1.245 - /*
1.246 - * We must clean up the "pending generation" state of the proxy
1.247 - * class cache entry somehow. If a proxy class was successfully
1.248 - * generated, store it in the cache (with a weak reference);
1.249 - * otherwise, remove the reserved entry. In all cases, notify
1.250 - * all waiters on reserved entries in this cache.
1.251 - */
1.252 - synchronized (cache) {
1.253 - if (proxyClass != null) {
1.254 - cache.put(key, new WeakReference<Class<?>>(proxyClass));
1.255 - } else {
1.256 - cache.remove(key);
1.257 - }
1.258 - cache.notifyAll();
1.259 - }
1.260 - }
1.261 - return proxyClass;
1.262 + throw new IllegalArgumentException();
1.263 }
1.264
1.265 /**
1.266 @@ -594,27 +355,7 @@
1.267 if (h == null) {
1.268 throw new NullPointerException();
1.269 }
1.270 -
1.271 - /*
1.272 - * Look up or generate the designated proxy class.
1.273 - */
1.274 - Class<?> cl = getProxyClass(loader, interfaces);
1.275 -
1.276 - /*
1.277 - * Invoke its constructor with the designated invocation handler.
1.278 - */
1.279 - try {
1.280 - Constructor cons = cl.getConstructor(constructorParams);
1.281 - return cons.newInstance(new Object[] { h });
1.282 - } catch (NoSuchMethodException e) {
1.283 - throw new InternalError(e.toString());
1.284 - } catch (IllegalAccessException e) {
1.285 - throw new InternalError(e.toString());
1.286 - } catch (InstantiationException e) {
1.287 - throw new InternalError(e.toString());
1.288 - } catch (InvocationTargetException e) {
1.289 - throw new InternalError(e.toString());
1.290 - }
1.291 + throw new IllegalArgumentException();
1.292 }
1.293
1.294 /**
1.295 @@ -636,7 +377,7 @@
1.296 throw new NullPointerException();
1.297 }
1.298
1.299 - return proxyClasses.containsKey(cl);
1.300 + return false;
1.301 }
1.302
1.303 /**