Proxy.java revision b1396870f92135aa140bd2b86221768dea5bc11d
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.lang.reflect; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.WeakReference; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.WeakHashMap; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-removed 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// import org.apache.harmony.luni.internal.reflect.ProxyClassFile; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-removed 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Proxy} defines methods for creating dynamic proxy classes and instances. 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A proxy class implements a declared set of interfaces and delegates method 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invocations to an {@code InvocationHandler}. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see InvocationHandler 36f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.3 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Proxy implements Serializable { 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -2222568056686623797L; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // maps class loaders to created classes by interface names 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>(); 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to find previously created types 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Map<Class<?>, String> proxyCache = new WeakHashMap<Class<?>, String>(); 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static int NextClassNameIndex = 0; 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The invocation handler on which the method calls are dispatched. 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected InvocationHandler h; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unused") 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Proxy() { 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new {@code Proxy} instance with the specified invocation 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handler. 62f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param h 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the invocation handler for the newly created proxy 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Proxy(InvocationHandler h) { 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.h = h; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the dynamically built {@code Class} for the specified interfaces. 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new {@code Class} when necessary. The order of the interfaces 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is relevant. Invocations of this method with the same interfaces but 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * different order result in different generated classes. The interfaces 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * must be visible from the supplied class loader; no duplicates are 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * permitted. All non-public interfaces must be defined in the same package. 77f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loader 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class loader that will define the proxy class 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param interfaces 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an array of {@code Class} objects, each one identifying an 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interface that will be implemented by the returned proxy 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a proxy class that implements all of the interfaces referred to 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the contents of {@code interfaces} 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any of the interface restrictions are violated 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if either {@code interfaces} or any of its elements are 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Class<?> getProxyClass(ClassLoader loader, 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?>... interfaces) throws IllegalArgumentException { 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-note 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Changed parameter to be closer to the RI 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-note 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check that interfaces are a valid array of visible interfaces 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (interfaces == null) { 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String commonPackageName = null; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0, length = interfaces.length; i < length; i++) { 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> next = interfaces[i]; 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (next == null) { 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = next.getName(); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!next.isInterface()) { 109b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException(name + " is not an interface"); 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (loader != next.getClassLoader()) { 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (next != Class.forName(name, false, loader)) { 114b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException(name + 115b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes " is not visible from class loader"); 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (ClassNotFoundException ex) { 118b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException(name + " is not visible from class loader"); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = i + 1; j < length; j++) { 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (next == interfaces[j]) { 123b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException(name + " appears more than once"); 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!Modifier.isPublic(next.getModifiers())) { 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int last = name.lastIndexOf('.'); 128f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String p = last == -1 ? "" : name.substring(0, last); 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (commonPackageName == null) { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project commonPackageName = p; 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (!commonPackageName.equals(p)) { 132b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("non-public interfaces must be " + 133b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes "in the same package"); 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // search cache for matching proxy class using the class loader 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (loaderCache) { 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map<String, WeakReference<Class<?>>> interfaceCache = loaderCache 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .get(loader); 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (interfaceCache == null) { 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loaderCache 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .put( 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loader, 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (interfaceCache = new HashMap<String, WeakReference<Class<?>>>())); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String interfaceKey = ""; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (interfaces.length == 1) { 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project interfaceKey = interfaces[0].getName(); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project StringBuilder names = new StringBuilder(); 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0, length = interfaces.length; i < length; i++) { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project names.append(interfaces[i].getName()); 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project names.append(' '); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project interfaceKey = names.toString(); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> newClass; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project WeakReference<Class<?>> ref = interfaceCache.get(interfaceKey); 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ref == null) { 164f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String nextClassName = "$Proxy" + NextClassNameIndex++; 165f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (commonPackageName != null && commonPackageName.length() > 0) { 166f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes nextClassName = commonPackageName + "." + nextClassName; 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 169f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // byte[] classFileBytes = ProxyClassFile.generateBytes( 170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // nextClassName, interfaces); 171f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // newClass = defineClassImpl(loader, nextClassName.replace('.', 172f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // '/'), classFileBytes); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (loader == null) { 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loader = ClassLoader.getSystemClassLoader(); 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClass = generateProxy(nextClassName.replace('.', '/'), 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project interfaces, loader); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Need a weak reference to the class so it can 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // be unloaded if the class loader is discarded 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project interfaceCache.put(interfaceKey, new WeakReference<Class<?>>( 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClass)); 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (proxyCache) { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the value is unused 185f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes proxyCache.put(newClass, ""); 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newClass = ref.get(); 189f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson assert newClass != null : "\ninterfaceKey=\"" + interfaceKey + "\"" 190f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson + "\nloaderCache=\"" + loaderCache + "\"" 191f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson + "\nintfCache=\"" + interfaceCache + "\"" 192f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson + "\nproxyCache=\"" + proxyCache + "\""; 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return newClass; 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an instance of the dynamically built class for the specified 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interfaces. Method invocations on the returned instance are forwarded to 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specified invocation handler. The interfaces must be visible from the 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied class loader; no duplicates are permitted. All non-public 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interfaces must be defined in the same package. 204f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loader 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class loader that will define the proxy class 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param interfaces 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an array of {@code Class} objects, each one identifying an 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interface that will be implemented by the returned proxy 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param h 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the invocation handler that handles the dispatched method 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invocations 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new proxy object that delegates to the handler {@code h} 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any of the interface restrictions are violated 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the interfaces or any of its elements are null 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Object newProxyInstance(ClassLoader loader, 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?>[] interfaces, InvocationHandler h) 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalArgumentException { 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (h == null) { 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getProxyClass(loader, interfaces).getConstructor( 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new Class<?>[] { InvocationHandler.class }).newInstance( 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new Object[] { h }); 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NoSuchMethodException ex) { 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (InternalError) (new InternalError(ex.toString()) 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .initCause(ex)); 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IllegalAccessException ex) { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (InternalError) (new InternalError(ex.toString()) 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .initCause(ex)); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InstantiationException ex) { 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (InternalError) (new InternalError(ex.toString()) 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .initCause(ex)); 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InvocationTargetException ex) { 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Throwable target = ex.getTargetException(); 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw (InternalError) (new InternalError(target.toString()) 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .initCause(target)); 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether or not the specified class is a dynamically generated 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * proxy class. 249f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the class is a proxy class, {@code false} 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class is {@code null} 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static boolean isProxyClass(Class<?> cl) { 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cl == null) { 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (proxyCache) { 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return proxyCache.containsKey(cl); 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the invocation handler of the specified proxy instance. 268f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param proxy 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the proxy instance 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the invocation handler of the specified proxy instance 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the supplied {@code proxy} is not a proxy object 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static InvocationHandler getInvocationHandler(Object proxy) 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalArgumentException { 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isProxyClass(proxy.getClass())) { 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((Proxy) proxy).h; 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 282b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("not a proxy instance"); 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //private static native Class<?> defineClassImpl(ClassLoader classLoader, 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // String className, byte[] classFileBytes); 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project native private static Class generateProxy(String name, Class[] interfaces, 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader loader); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The VM clones this method's descriptor when generating a proxy class. 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There is no implementation. 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project native private static void constructorPrototype(InvocationHandler h); 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 299