Source Code Cross Referenced for Proxy.java in  » 6.0-JDK-Core » lang » java » lang » reflect » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » lang » java.lang.reflect 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.lang.reflect;
027
028        import java.lang.ref.Reference;
029        import java.lang.ref.WeakReference;
030        import java.util.Arrays;
031        import java.util.Collections;
032        import java.util.HashMap;
033        import java.util.HashSet;
034        import java.util.Map;
035        import java.util.Set;
036        import java.util.WeakHashMap;
037        import sun.misc.ProxyGenerator;
038
039        /**
040         * {@code Proxy} provides static methods for creating dynamic proxy
041         * classes and instances, and it is also the superclass of all
042         * dynamic proxy classes created by those methods.
043         *
044         * <p>To create a proxy for some interface {@code Foo}:
045         * <pre>
046         *     InvocationHandler handler = new MyInvocationHandler(...);
047         *     Class proxyClass = Proxy.getProxyClass(
048         *         Foo.class.getClassLoader(), new Class[] { Foo.class });
049         *     Foo f = (Foo) proxyClass.
050         *         getConstructor(new Class[] { InvocationHandler.class }).
051         *         newInstance(new Object[] { handler });
052         * </pre>
053         * or more simply:
054         * <pre>
055         *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
056         *                                          new Class[] { Foo.class },
057         *                                          handler);
058         * </pre>
059         *
060         * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
061         * class</i> below) is a class that implements a list of interfaces
062         * specified at runtime when the class is created, with behavior as
063         * described below.
064         *
065         * A <i>proxy interface</i> is such an interface that is implemented
066         * by a proxy class.
067         *
068         * A <i>proxy instance</i> is an instance of a proxy class.
069         *
070         * Each proxy instance has an associated <i>invocation handler</i>
071         * object, which implements the interface {@link InvocationHandler}.
072         * A method invocation on a proxy instance through one of its proxy
073         * interfaces will be dispatched to the {@link InvocationHandler#invoke
074         * invoke} method of the instance's invocation handler, passing the proxy
075         * instance, a {@code java.lang.reflect.Method} object identifying
076         * the method that was invoked, and an array of type {@code Object}
077         * containing the arguments.  The invocation handler processes the
078         * encoded method invocation as appropriate and the result that it
079         * returns will be returned as the result of the method invocation on
080         * the proxy instance.
081         *
082         * <p>A proxy class has the following properties:
083         *
084         * <ul>
085         * <li>Proxy classes are public, final, and not abstract.
086         *
087         * <li>The unqualified name of a proxy class is unspecified.  The space
088         * of class names that begin with the string {@code "$Proxy"}
089         * should be, however, reserved for proxy classes.
090         *
091         * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
092         *
093         * <li>A proxy class implements exactly the interfaces specified at its
094         * creation, in the same order.
095         *
096         * <li>If a proxy class implements a non-public interface, then it will
097         * be defined in the same package as that interface.  Otherwise, the
098         * package of a proxy class is also unspecified.  Note that package
099         * sealing will not prevent a proxy class from being successfully defined
100         * in a particular package at runtime, and neither will classes already
101         * defined by the same class loader and the same package with particular
102         * signers.
103         *
104         * <li>Since a proxy class implements all of the interfaces specified at
105         * its creation, invoking {@code getInterfaces} on its
106         * {@code Class} object will return an array containing the same
107         * list of interfaces (in the order specified at its creation), invoking
108         * {@code getMethods} on its {@code Class} object will return
109         * an array of {@code Method} objects that include all of the
110         * methods in those interfaces, and invoking {@code getMethod} will
111         * find methods in the proxy interfaces as would be expected.
112         *
113         * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
114         * return true if it is passed a proxy class-- a class returned by
115         * {@code Proxy.getProxyClass} or the class of an object returned by
116         * {@code Proxy.newProxyInstance}-- and false otherwise.
117         *
118         * <li>The {@code java.security.ProtectionDomain} of a proxy class
119         * is the same as that of system classes loaded by the bootstrap class
120         * loader, such as {@code java.lang.Object}, because the code for a
121         * proxy class is generated by trusted system code.  This protection
122         * domain will typically be granted
123         * {@code java.security.AllPermission}.
124         *
125         * <li>Each proxy class has one public constructor that takes one argument,
126         * an implementation of the interface {@link InvocationHandler}, to set
127         * the invocation handler for a proxy instance.  Rather than having to use
128         * the reflection API to access the public constructor, a proxy instance
129         * can be also be created by calling the {@link Proxy#newProxyInstance
130         * Proxy.newProxyInstance} method, which combines the actions of calling
131         * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
132         * constructor with an invocation handler.
133         * </ul>
134         *
135         * <p>A proxy instance has the following properties:
136         *
137         * <ul>
138         * <li>Given a proxy instance {@code proxy} and one of the
139         * interfaces implemented by its proxy class {@code Foo}, the
140         * following expression will return true:
141         * <pre>
142         *     {@code proxy instanceof Foo}
143         * </pre>
144         * and the following cast operation will succeed (rather than throwing
145         * a {@code ClassCastException}):
146         * <pre>
147         *     {@code (Foo) proxy}
148         * </pre>
149         *
150         * <li>Each proxy instance has an associated invocation handler, the one
151         * that was passed to its constructor.  The static
152         * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
153         * will return the invocation handler associated with the proxy instance
154         * passed as its argument.
155         *
156         * <li>An interface method invocation on a proxy instance will be
157         * encoded and dispatched to the invocation handler's {@link
158         * InvocationHandler#invoke invoke} method as described in the
159         * documentation for that method.
160         *
161         * <li>An invocation of the {@code hashCode},
162         * {@code equals}, or {@code toString} methods declared in
163         * {@code java.lang.Object} on a proxy instance will be encoded and
164         * dispatched to the invocation handler's {@code invoke} method in
165         * the same manner as interface method invocations are encoded and
166         * dispatched, as described above.  The declaring class of the
167         * {@code Method} object passed to {@code invoke} will be
168         * {@code java.lang.Object}.  Other public methods of a proxy
169         * instance inherited from {@code java.lang.Object} are not
170         * overridden by a proxy class, so invocations of those methods behave
171         * like they do for instances of {@code java.lang.Object}.
172         * </ul>
173         *
174         * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
175         *
176         * <p>When two or more interfaces of a proxy class contain a method with
177         * the same name and parameter signature, the order of the proxy class's
178         * interfaces becomes significant.  When such a <i>duplicate method</i>
179         * is invoked on a proxy instance, the {@code Method} object passed
180         * to the invocation handler will not necessarily be the one whose
181         * declaring class is assignable from the reference type of the interface
182         * that the proxy's method was invoked through.  This limitation exists
183         * because the corresponding method implementation in the generated proxy
184         * class cannot determine which interface it was invoked through.
185         * Therefore, when a duplicate method is invoked on a proxy instance,
186         * the {@code Method} object for the method in the foremost interface
187         * that contains the method (either directly or inherited through a
188         * superinterface) in the proxy class's list of interfaces is passed to
189         * the invocation handler's {@code invoke} method, regardless of the
190         * reference type through which the method invocation occurred.
191         *
192         * <p>If a proxy interface contains a method with the same name and
193         * parameter signature as the {@code hashCode}, {@code equals},
194         * or {@code toString} methods of {@code java.lang.Object},
195         * when such a method is invoked on a proxy instance, the
196         * {@code Method} object passed to the invocation handler will have
197         * {@code java.lang.Object} as its declaring class.  In other words,
198         * the public, non-final methods of {@code java.lang.Object}
199         * logically precede all of the proxy interfaces for the determination of
200         * which {@code Method} object to pass to the invocation handler.
201         *
202         * <p>Note also that when a duplicate method is dispatched to an
203         * invocation handler, the {@code invoke} method may only throw
204         * checked exception types that are assignable to one of the exception
205         * types in the {@code throws} clause of the method in <i>all</i> of
206         * the proxy interfaces that it can be invoked through.  If the
207         * {@code invoke} method throws a checked exception that is not
208         * assignable to any of the exception types declared by the method in one
209         * of the proxy interfaces that it can be invoked through, then an
210         * unchecked {@code UndeclaredThrowableException} will be thrown by
211         * the invocation on the proxy instance.  This restriction means that not
212         * all of the exception types returned by invoking
213         * {@code getExceptionTypes} on the {@code Method} object
214         * passed to the {@code invoke} method can necessarily be thrown
215         * successfully by the {@code invoke} method.
216         *
217         * @author	Peter Jones
218         * @version	1.30, 07/06/22
219         * @see		InvocationHandler
220         * @since	1.3
221         */
222        public class Proxy implements  java.io.Serializable {
223
224            private static final long serialVersionUID = -2222568056686623797L;
225
226            /** prefix for all proxy class names */
227            private final static String proxyClassNamePrefix = "$Proxy";
228
229            /** parameter types of a proxy class constructor */
230            private final static Class[] constructorParams = { InvocationHandler.class };
231
232            /** maps a class loader to the proxy class cache for that loader */
233            private static Map loaderToCache = new WeakHashMap();
234
235            /** marks that a particular proxy class is currently being generated */
236            private static Object pendingGenerationMarker = new Object();
237
238            /** next number to use for generation of unique proxy class names */
239            private static long nextUniqueNumber = 0;
240            private static Object nextUniqueNumberLock = new Object();
241
242            /** set of all generated proxy classes, for isProxyClass implementation */
243            private static Map proxyClasses = Collections
244                    .synchronizedMap(new WeakHashMap());
245
246            /**
247             * the invocation handler for this proxy instance.
248             * @serial
249             */
250            protected InvocationHandler h;
251
252            /**
253             * Prohibits instantiation.
254             */
255            private Proxy() {
256            }
257
258            /**
259             * Constructs a new {@code Proxy} instance from a subclass
260             * (typically, a dynamic proxy class) with the specified value
261             * for its invocation handler.
262             *
263             * @param   h the invocation handler for this proxy instance
264             */
265            protected Proxy(InvocationHandler h) {
266                this .h = h;
267            }
268
269            /**
270             * Returns the {@code java.lang.Class} object for a proxy class
271             * given a class loader and an array of interfaces.  The proxy class
272             * will be defined by the specified class loader and will implement
273             * all of the supplied interfaces.  If a proxy class for the same
274             * permutation of interfaces has already been defined by the class
275             * loader, then the existing proxy class will be returned; otherwise,
276             * a proxy class for those interfaces will be generated dynamically
277             * and defined by the class loader.
278             *
279             * <p>There are several restrictions on the parameters that may be
280             * passed to {@code Proxy.getProxyClass}:
281             *
282             * <ul>
283             * <li>All of the {@code Class} objects in the
284             * {@code interfaces} array must represent interfaces, not
285             * classes or primitive types.
286             *
287             * <li>No two elements in the {@code interfaces} array may
288             * refer to identical {@code Class} objects.
289             *
290             * <li>All of the interface types must be visible by name through the
291             * specified class loader.  In other words, for class loader
292             * {@code cl} and every interface {@code i}, the following
293             * expression must be true:
294             * <pre>
295             *     Class.forName(i.getName(), false, cl) == i
296             * </pre>
297             *
298             * <li>All non-public interfaces must be in the same package;
299             * otherwise, it would not be possible for the proxy class to
300             * implement all of the interfaces, regardless of what package it is
301             * defined in.
302             *
303             * <li>For any set of member methods of the specified interfaces
304             * that have the same signature:
305             * <ul>
306             * <li>If the return type of any of the methods is a primitive
307             * type or void, then all of the methods must have that same
308             * return type.
309             * <li>Otherwise, one of the methods must have a return type that
310             * is assignable to all of the return types of the rest of the
311             * methods.
312             * </ul>
313             *
314             * <li>The resulting proxy class must not exceed any limits imposed
315             * on classes by the virtual machine.  For example, the VM may limit
316             * the number of interfaces that a class may implement to 65535; in
317             * that case, the size of the {@code interfaces} array must not
318             * exceed 65535.
319             * </ul>
320             *
321             * <p>If any of these restrictions are violated,
322             * {@code Proxy.getProxyClass} will throw an
323             * {@code IllegalArgumentException}.  If the {@code interfaces}
324             * array argument or any of its elements are {@code null}, a
325             * {@code NullPointerException} will be thrown.
326             *
327             * <p>Note that the order of the specified proxy interfaces is
328             * significant: two requests for a proxy class with the same combination
329             * of interfaces but in a different order will result in two distinct
330             * proxy classes.
331             *
332             * @param	loader the class loader to define the proxy class
333             * @param	interfaces the list of interfaces for the proxy class
334             *		to implement
335             * @return	a proxy class that is defined in the specified class loader
336             *		and that implements the specified interfaces
337             * @throws	IllegalArgumentException if any of the restrictions on the
338             *		parameters that may be passed to {@code getProxyClass}
339             *		are violated
340             * @throws	NullPointerException if the {@code interfaces} array
341             *		argument or any of its elements are {@code null}
342             */
343            public static Class<?> getProxyClass(ClassLoader loader,
344                    Class<?>... interfaces) throws IllegalArgumentException {
345                if (interfaces.length > 65535) {
346                    throw new IllegalArgumentException(
347                            "interface limit exceeded");
348                }
349
350                Class proxyClass = null;
351
352                /* collect interface names to use as key for proxy class cache */
353                String[] interfaceNames = new String[interfaces.length];
354
355                Set interfaceSet = new HashSet(); // for detecting duplicates
356
357                for (int i = 0; i < interfaces.length; i++) {
358                    /*
359                     * Verify that the class loader resolves the name of this
360                     * interface to the same Class object.
361                     */
362                    String interfaceName = interfaces[i].getName();
363                    Class interfaceClass = null;
364                    try {
365                        interfaceClass = Class.forName(interfaceName, false,
366                                loader);
367                    } catch (ClassNotFoundException e) {
368                    }
369                    if (interfaceClass != interfaces[i]) {
370                        throw new IllegalArgumentException(interfaces[i]
371                                + " is not visible from class loader");
372                    }
373
374                    /*
375                     * Verify that the Class object actually represents an
376                     * interface.
377                     */
378                    if (!interfaceClass.isInterface()) {
379                        throw new IllegalArgumentException(interfaceClass
380                                .getName()
381                                + " is not an interface");
382                    }
383
384                    /*
385                     * Verify that this interface is not a duplicate.
386                     */
387                    if (interfaceSet.contains(interfaceClass)) {
388                        throw new IllegalArgumentException(
389                                "repeated interface: "
390                                        + interfaceClass.getName());
391                    }
392                    interfaceSet.add(interfaceClass);
393
394                    interfaceNames[i] = interfaceName;
395                }
396
397                /*
398                 * Using string representations of the proxy interfaces as
399                 * keys in the proxy class cache (instead of their Class
400                 * objects) is sufficient because we require the proxy
401                 * interfaces to be resolvable by name through the supplied
402                 * class loader, and it has the advantage that using a string
403                 * representation of a class makes for an implicit weak
404                 * reference to the class.
405                 */
406                Object key = Arrays.asList(interfaceNames);
407
408                /*
409                 * Find or create the proxy class cache for the class loader.
410                 */
411                Map cache;
412                synchronized (loaderToCache) {
413                    cache = (Map) loaderToCache.get(loader);
414                    if (cache == null) {
415                        cache = new HashMap();
416                        loaderToCache.put(loader, cache);
417                    }
418                    /*
419                     * This mapping will remain valid for the duration of this
420                     * method, without further synchronization, because the mapping
421                     * will only be removed if the class loader becomes unreachable.
422                     */
423                }
424
425                /*
426                 * Look up the list of interfaces in the proxy class cache using
427                 * the key.  This lookup will result in one of three possible
428                 * kinds of values:
429                 *     null, if there is currently no proxy class for the list of
430                 *         interfaces in the class loader,
431                 *     the pendingGenerationMarker object, if a proxy class for the
432                 *         list of interfaces is currently being generated,
433                 *     or a weak reference to a Class object, if a proxy class for
434                 *         the list of interfaces has already been generated.
435                 */
436                synchronized (cache) {
437                    /*
438                     * Note that we need not worry about reaping the cache for
439                     * entries with cleared weak references because if a proxy class
440                     * has been garbage collected, its class loader will have been
441                     * garbage collected as well, so the entire cache will be reaped
442                     * from the loaderToCache map.
443                     */
444                    do {
445                        Object value = cache.get(key);
446                        if (value instanceof  Reference) {
447                            proxyClass = (Class) ((Reference) value).get();
448                        }
449                        if (proxyClass != null) {
450                            // proxy class already generated: return it
451                            return proxyClass;
452                        } else if (value == pendingGenerationMarker) {
453                            // proxy class being generated: wait for it
454                            try {
455                                cache.wait();
456                            } catch (InterruptedException e) {
457                                /*
458                                 * The class generation that we are waiting for should
459                                 * take a small, bounded time, so we can safely ignore
460                                 * thread interrupts here.
461                                 */
462                            }
463                            continue;
464                        } else {
465                            /*
466                             * No proxy class for this list of interfaces has been
467                             * generated or is being generated, so we will go and
468                             * generate it now.  Mark it as pending generation.
469                             */
470                            cache.put(key, pendingGenerationMarker);
471                            break;
472                        }
473                    } while (true);
474                }
475
476                try {
477                    String proxyPkg = null; // package to define proxy class in
478
479                    /*
480                     * Record the package of a non-public proxy interface so that the
481                     * proxy class will be defined in the same package.  Verify that
482                     * all non-public proxy interfaces are in the same package.
483                     */
484                    for (int i = 0; i < interfaces.length; i++) {
485                        int flags = interfaces[i].getModifiers();
486                        if (!Modifier.isPublic(flags)) {
487                            String name = interfaces[i].getName();
488                            int n = name.lastIndexOf('.');
489                            String pkg = ((n == -1) ? "" : name.substring(0,
490                                    n + 1));
491                            if (proxyPkg == null) {
492                                proxyPkg = pkg;
493                            } else if (!pkg.equals(proxyPkg)) {
494                                throw new IllegalArgumentException(
495                                        "non-public interfaces from different packages");
496                            }
497                        }
498                    }
499
500                    if (proxyPkg == null) { // if no non-public proxy interfaces,
501                        proxyPkg = ""; // use the unnamed package
502                    }
503
504                    {
505                        /*
506                         * Choose a name for the proxy class to generate.
507                         */
508                        long num;
509                        synchronized (nextUniqueNumberLock) {
510                            num = nextUniqueNumber++;
511                        }
512                        String proxyName = proxyPkg + proxyClassNamePrefix
513                                + num;
514                        /*
515                         * Verify that the class loader hasn't already
516                         * defined a class with the chosen name.
517                         */
518
519                        /*
520                         * Generate the specified proxy class.
521                         */
522                        byte[] proxyClassFile = ProxyGenerator
523                                .generateProxyClass(proxyName, interfaces);
524                        try {
525                            proxyClass = defineClass0(loader, proxyName,
526                                    proxyClassFile, 0, proxyClassFile.length);
527                        } catch (ClassFormatError e) {
528                            /*
529                             * A ClassFormatError here means that (barring bugs in the
530                             * proxy class generation code) there was some other
531                             * invalid aspect of the arguments supplied to the proxy
532                             * class creation (such as virtual machine limitations
533                             * exceeded).
534                             */
535                            throw new IllegalArgumentException(e.toString());
536                        }
537                    }
538                    // add to set of all generated proxy classes, for isProxyClass
539                    proxyClasses.put(proxyClass, null);
540
541                } finally {
542                    /*
543                     * We must clean up the "pending generation" state of the proxy
544                     * class cache entry somehow.  If a proxy class was successfully
545                     * generated, store it in the cache (with a weak reference);
546                     * otherwise, remove the reserved entry.  In all cases, notify
547                     * all waiters on reserved entries in this cache.
548                     */
549                    synchronized (cache) {
550                        if (proxyClass != null) {
551                            cache.put(key, new WeakReference(proxyClass));
552                        } else {
553                            cache.remove(key);
554                        }
555                        cache.notifyAll();
556                    }
557                }
558                return proxyClass;
559            }
560
561            /**
562             * Returns an instance of a proxy class for the specified interfaces
563             * that dispatches method invocations to the specified invocation
564             * handler.  This method is equivalent to:
565             * <pre>
566             *     Proxy.getProxyClass(loader, interfaces).
567             *         getConstructor(new Class[] { InvocationHandler.class }).
568             *         newInstance(new Object[] { handler });
569             * </pre>
570             *
571             * <p>{@code Proxy.newProxyInstance} throws
572             * {@code IllegalArgumentException} for the same reasons that
573             * {@code Proxy.getProxyClass} does.
574             *
575             * @param	loader the class loader to define the proxy class
576             * @param	interfaces the list of interfaces for the proxy class
577             *		to implement
578             * @param   h the invocation handler to dispatch method invocations to
579             * @return	a proxy instance with the specified invocation handler of a
580             *		proxy class that is defined by the specified class loader
581             *		and that implements the specified interfaces
582             * @throws	IllegalArgumentException if any of the restrictions on the
583             *		parameters that may be passed to {@code getProxyClass}
584             *		are violated
585             * @throws	NullPointerException if the {@code interfaces} array
586             *		argument or any of its elements are {@code null}, or
587             *		if the invocation handler, {@code h}, is
588             *		{@code null}
589             */
590            public static Object newProxyInstance(ClassLoader loader,
591                    Class<?>[] interfaces, InvocationHandler h)
592                    throws IllegalArgumentException {
593                if (h == null) {
594                    throw new NullPointerException();
595                }
596
597                /*
598                 * Look up or generate the designated proxy class.
599                 */
600                Class cl = getProxyClass(loader, interfaces);
601
602                /*
603                 * Invoke its constructor with the designated invocation handler.
604                 */
605                try {
606                    Constructor cons = cl.getConstructor(constructorParams);
607                    return (Object) cons.newInstance(new Object[] { h });
608                } catch (NoSuchMethodException e) {
609                    throw new InternalError(e.toString());
610                } catch (IllegalAccessException e) {
611                    throw new InternalError(e.toString());
612                } catch (InstantiationException e) {
613                    throw new InternalError(e.toString());
614                } catch (InvocationTargetException e) {
615                    throw new InternalError(e.toString());
616                }
617            }
618
619            /**
620             * Returns true if and only if the specified class was dynamically
621             * generated to be a proxy class using the {@code getProxyClass}
622             * method or the {@code newProxyInstance} method.
623             *
624             * <p>The reliability of this method is important for the ability
625             * to use it to make security decisions, so its implementation should
626             * not just test if the class in question extends {@code Proxy}.
627             *
628             * @param	cl the class to test
629             * @return  {@code true} if the class is a proxy class and
630             *		{@code false} otherwise
631             * @throws	NullPointerException if {@code cl} is {@code null}
632             */
633            public static boolean isProxyClass(Class<?> cl) {
634                if (cl == null) {
635                    throw new NullPointerException();
636                }
637
638                return proxyClasses.containsKey(cl);
639            }
640
641            /**
642             * Returns the invocation handler for the specified proxy instance.
643             *
644             * @param	proxy the proxy instance to return the invocation handler for
645             * @return	the invocation handler for the proxy instance
646             * @throws	IllegalArgumentException if the argument is not a
647             *		proxy instance
648             */
649            public static InvocationHandler getInvocationHandler(Object proxy)
650                    throws IllegalArgumentException {
651                /*
652                 * Verify that the object is actually a proxy instance.
653                 */
654                if (!isProxyClass(proxy.getClass())) {
655                    throw new IllegalArgumentException("not a proxy instance");
656                }
657
658                Proxy p = (Proxy) proxy;
659                return p.h;
660            }
661
662            private static native Class defineClass0(ClassLoader loader,
663                    String name, byte[] b, int off, int len);
664        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.