java.lang.reflect.Proxy#getInvocationHandler ( )源码实例Demo

下面列出了java.lang.reflect.Proxy#getInvocationHandler ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: arcusplatform   文件: ModelInvocationFunctions.java
@Override
public Object invoke(Model delegate, Method method, Object[] args) throws Exception {
	if(args.length != 1 || args[0] == null) {
		return false;
	}
	Object other = args[0];
	if(Proxy.isProxyClass(other.getClass())) {
		InvocationHandler handler = Proxy.getInvocationHandler(other);
		if(handler instanceof ModelInvocationHandler) {
			return delegate.equals(((ModelInvocationHandler) handler).getDelegate());
		}
	}
	if(other instanceof Model) {
		return delegate.equals(other);
	}
	return false;
}
 
源代码2 项目: dragonwell8_jdk   文件: TestUtils.java
/**
 * Transfroms a proxy implementing T in a proxy implementing T plus
 * NotificationEmitter
 *
 **/
public static <T> T makeNotificationEmitter(T proxy,
                    Class<T> mbeanInterface) {
    if (proxy instanceof NotificationEmitter)
        return proxy;
    if (proxy == null) return null;
    if (!(proxy instanceof Proxy))
        throw new IllegalArgumentException("not a "+Proxy.class.getName());
    final Proxy p = (Proxy) proxy;
    final InvocationHandler handler =
            Proxy.getInvocationHandler(proxy);
    if (!(handler instanceof MBeanServerInvocationHandler))
        throw new IllegalArgumentException("not a JMX Proxy");
    final MBeanServerInvocationHandler h =
            (MBeanServerInvocationHandler)handler;
    final ObjectName name = h.getObjectName();
    final MBeanServerConnection mbs = h.getMBeanServerConnection();
    final boolean isMXBean = h.isMXBean();
    final T newProxy;
    if (isMXBean)
        newProxy = JMX.newMXBeanProxy(mbs,name,mbeanInterface,true);
    else
        newProxy = JMX.newMBeanProxy(mbs,name,mbeanInterface,true);
    return newProxy;
}
 
源代码3 项目: TencentKona-8   文件: MXBeanTest.java
static boolean equal(Object o1, Object o2, NamedMXBeans namedMXBeans) {
        if (o1 == o2)
            return true;
        if (o1 == null || o2 == null)
            return false;
        if (o1.getClass().isArray()) {
            if (!o2.getClass().isArray())
                return false;
            return deepEqual(o1, o2, namedMXBeans);
        }
        if (o1 instanceof Map) {
            if (!(o2 instanceof Map))
                return false;
            return equalMap((Map) o1, (Map) o2, namedMXBeans);
        }
        if (o1 instanceof CompositeData && o2 instanceof CompositeData) {
            return compositeDataEqual((CompositeData) o1, (CompositeData) o2,
                                      namedMXBeans);
        }
        if (Proxy.isProxyClass(o1.getClass())) {
            if (Proxy.isProxyClass(o2.getClass()))
                return proxyEqual(o1, o2, namedMXBeans);
            InvocationHandler ih = Proxy.getInvocationHandler(o1);
//            if (ih instanceof MXBeanInvocationHandler) {
//                return proxyEqualsObject((MXBeanInvocationHandler) ih,
//                                         o2, namedMXBeans);
            if (ih instanceof MBeanServerInvocationHandler) {
                return true;
            } else if (ih instanceof CompositeDataInvocationHandler) {
                return o2.equals(o1);
                // We assume the other object has a reasonable equals method
            }
        } else if (Proxy.isProxyClass(o2.getClass()))
            return equal(o2, o1, namedMXBeans);
        return o1.equals(o2);
    }
 
源代码4 项目: TencentKona-8   文件: RemoteObject.java
/**
 * Returns the stub for the remote object <code>obj</code> passed
 * as a parameter. This operation is only valid <i>after</i>
 * the object has been exported.
 * @param obj the remote object whose stub is needed
 * @return the stub for the remote object, <code>obj</code>.
 * @exception NoSuchObjectException if the stub for the
 * remote object could not be found.
 * @since 1.2
 */
public static Remote toStub(Remote obj) throws NoSuchObjectException {
    if (obj instanceof RemoteStub ||
        (obj != null &&
         Proxy.isProxyClass(obj.getClass()) &&
         Proxy.getInvocationHandler(obj) instanceof
         RemoteObjectInvocationHandler))
    {
        return obj;
    } else {
        return sun.rmi.transport.ObjectTable.getStub(obj);
    }
}
 
private Object doLocally(Object proxy, Method method, Object[] args) {
    final String methodName = method.getName();

    if (methodName.equals("equals")) {

        if (this == args[0]) {
            return true;
        }

        if (!(args[0] instanceof Proxy)) {
            return false;
        }

        final InvocationHandler ihandler =
            Proxy.getInvocationHandler(args[0]);

        if (ihandler == null ||
            !(ihandler instanceof MBeanServerInvocationHandler)) {
            return false;
        }

        final MBeanServerInvocationHandler handler =
            (MBeanServerInvocationHandler)ihandler;

        return connection.equals(handler.connection) &&
            objectName.equals(handler.objectName) &&
            proxy.getClass().equals(args[0].getClass());
    } else if (methodName.equals("toString")) {
        return (isMXBean() ? "MX" : "M") + "BeanProxy(" +
            connection + "[" + objectName + "])";
    } else if (methodName.equals("hashCode")) {
        return objectName.hashCode()+connection.hashCode();
    } else if (methodName.equals("finalize")) {
        // ignore the finalizer invocation via proxy
        return null;
    }

    throw new RuntimeException("Unexpected method name: " + methodName);
}
 
/**
 * Equality means interfaces, advisors and TargetSource are equal.
 * <p>The compared object may be a JdkDynamicAopProxy instance itself
 * or a dynamic proxy wrapping a JdkDynamicAopProxy instance.
 */
@Override
public boolean equals(@Nullable Object other) {
	if (other == this) {
		return true;
	}
	if (other == null) {
		return false;
	}

	JdkDynamicAopProxy otherProxy;
	if (other instanceof JdkDynamicAopProxy) {
		otherProxy = (JdkDynamicAopProxy) other;
	}
	else if (Proxy.isProxyClass(other.getClass())) {
		InvocationHandler ih = Proxy.getInvocationHandler(other);
		if (!(ih instanceof JdkDynamicAopProxy)) {
			return false;
		}
		otherProxy = (JdkDynamicAopProxy) ih;
	}
	else {
		// Not a valid comparison...
		return false;
	}

	// If we get here, otherProxy is the other AopProxy.
	return AopProxyUtils.equalsInProxy(this.advised, otherProxy.advised);
}
 
源代码7 项目: TencentKona-8   文件: TestUtils.java
/**
 * Returns the ObjectName of the MBean that a proxy object
 * is proxying.
 **/
public static ObjectName getObjectName(Object proxy) {
    if (!(proxy instanceof Proxy))
        throw new IllegalArgumentException("not a "+Proxy.class.getName());
    final Proxy p = (Proxy) proxy;
    final InvocationHandler handler =
            Proxy.getInvocationHandler(proxy);
    if (handler instanceof MBeanServerInvocationHandler)
        return ((MBeanServerInvocationHandler)handler).getObjectName();
    throw new IllegalArgumentException("not a JMX Proxy");
}
 
/**
 * Handles java.lang.Object methods.
 **/
private Object invokeObjectMethod(Object proxy,
                                  Method method,
                                  Object[] args)
{
    String name = method.getName();

    if (name.equals("hashCode")) {
        return hashCode();

    } else if (name.equals("equals")) {
        Object obj = args[0];
        InvocationHandler hdlr;
        return
            proxy == obj ||
            (obj != null &&
             Proxy.isProxyClass(obj.getClass()) &&
             (hdlr = Proxy.getInvocationHandler(obj)) instanceof RemoteObjectInvocationHandler &&
             this.equals(hdlr));

    } else if (name.equals("toString")) {
        return proxyToString(proxy);

    } else {
        throw new IllegalArgumentException(
            "unexpected Object method: " + method);
    }
}
 
private Object doLocally(Object proxy, Method method, Object[] args) {
    final String methodName = method.getName();

    if (methodName.equals("equals")) {

        if (this == args[0]) {
            return true;
        }

        if (!(args[0] instanceof Proxy)) {
            return false;
        }

        final InvocationHandler ihandler =
            Proxy.getInvocationHandler(args[0]);

        if (ihandler == null ||
            !(ihandler instanceof MBeanServerInvocationHandler)) {
            return false;
        }

        final MBeanServerInvocationHandler handler =
            (MBeanServerInvocationHandler)ihandler;

        return connection.equals(handler.connection) &&
            objectName.equals(handler.objectName) &&
            proxy.getClass().equals(args[0].getClass());
    } else if (methodName.equals("toString")) {
        return (isMXBean() ? "MX" : "M") + "BeanProxy(" +
            connection + "[" + objectName + "])";
    } else if (methodName.equals("hashCode")) {
        return objectName.hashCode()+connection.hashCode();
    } else if (methodName.equals("finalize")) {
        // ignore the finalizer invocation via proxy
        return null;
    }

    throw new RuntimeException("Unexpected method name: " + methodName);
}
 
源代码10 项目: dragonwell8_jdk   文件: ReflectionExceptionTest.java
/**
 * Test the monitor notifications.
 */
public int monitorNotifications() throws Exception {

    server = MBeanServerFactory.newMBeanServer();

    MBeanServerForwarderInvocationHandler mbsfih =
        (MBeanServerForwarderInvocationHandler)
        Proxy.getInvocationHandler(server);

    mbsfih.setGetAttributeException(
        new ReflectionException(new RuntimeException(),
                                "Test ReflectionException"));

    domain = server.getDefaultDomain();

    obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject");
    server.registerMBean(new ObservedObject(), obsObjName);

    echo(">>> ----------------------------------------");
    int error = counterMonitorNotification();
    echo(">>> ----------------------------------------");
    error += gaugeMonitorNotification();
    echo(">>> ----------------------------------------");
    error += stringMonitorNotification();
    echo(">>> ----------------------------------------");
    return error;
}
 
源代码11 项目: java-technology-stack   文件: BshScriptUtils.java
private boolean isProxyForSameBshObject(Object other) {
	if (!Proxy.isProxyClass(other.getClass())) {
		return false;
	}
	InvocationHandler ih = Proxy.getInvocationHandler(other);
	return (ih instanceof BshObjectInvocationHandler &&
			this.xt.equals(((BshObjectInvocationHandler) ih).xt));
}
 
源代码12 项目: dragonwell8_jdk   文件: MXBeanTest.java
private static boolean proxyEqual(Object proxy1, Object proxy2,
                                  NamedMXBeans namedMXBeans) {
    if (proxy1.getClass() != proxy2.getClass())
        return proxy1.equals(proxy2);
    InvocationHandler ih1 = Proxy.getInvocationHandler(proxy1);
    InvocationHandler ih2 = Proxy.getInvocationHandler(proxy2);
    if (!(ih1 instanceof CompositeDataInvocationHandler)
        || !(ih2 instanceof CompositeDataInvocationHandler))
        return proxy1.equals(proxy2);
    CompositeData cd1 =
        ((CompositeDataInvocationHandler) ih1).getCompositeData();
    CompositeData cd2 =
        ((CompositeDataInvocationHandler) ih2).getCompositeData();
    return compositeDataEqual(cd1, cd2, namedMXBeans);
}
 
private boolean equals(Object proxy, Object other) {
    if (other == null)
        return false;

    final Class<?> proxyClass = proxy.getClass();
    final Class<?> otherClass = other.getClass();
    if (proxyClass != otherClass)
        return false;
    InvocationHandler otherih = Proxy.getInvocationHandler(other);
    if (!(otherih instanceof CompositeDataInvocationHandler))
        return false;
    CompositeDataInvocationHandler othercdih =
        (CompositeDataInvocationHandler) otherih;
    return compositeData.equals(othercdih.compositeData);
}
 
/**
 * Handles java.lang.Object methods.
 **/
private Object invokeObjectMethod(Object proxy,
                                  Method method,
                                  Object[] args)
{
    String name = method.getName();

    if (name.equals("hashCode")) {
        return hashCode();

    } else if (name.equals("equals")) {
        Object obj = args[0];
        InvocationHandler hdlr;
        return
            proxy == obj ||
            (obj != null &&
             Proxy.isProxyClass(obj.getClass()) &&
             (hdlr = Proxy.getInvocationHandler(obj)) instanceof RemoteObjectInvocationHandler &&
             this.equals(hdlr));

    } else if (name.equals("toString")) {
        return proxyToString(proxy);

    } else {
        throw new IllegalArgumentException(
            "unexpected Object method: " + method);
    }
}
 
源代码15 项目: TencentKona-8   文件: MXBeanTest.java
private static boolean proxyEqual(Object proxy1, Object proxy2,
                                  NamedMXBeans namedMXBeans) {
    if (proxy1.getClass() != proxy2.getClass())
        return proxy1.equals(proxy2);
    InvocationHandler ih1 = Proxy.getInvocationHandler(proxy1);
    InvocationHandler ih2 = Proxy.getInvocationHandler(proxy2);
    if (!(ih1 instanceof CompositeDataInvocationHandler)
        || !(ih2 instanceof CompositeDataInvocationHandler))
        return proxy1.equals(proxy2);
    CompositeData cd1 =
        ((CompositeDataInvocationHandler) ih1).getCompositeData();
    CompositeData cd2 =
        ((CompositeDataInvocationHandler) ih2).getCompositeData();
    return compositeDataEqual(cd1, cd2, namedMXBeans);
}
 
源代码16 项目: TencentKona-8   文件: ActivationID.java
/**
 * <code>writeObject</code> for custom serialization.
 *
 * <p>This method writes this object's serialized form for
 * this class as follows:
 *
 * <p>The <code>writeObject</code> method is invoked on
 * <code>out</code> passing this object's unique identifier
 * (a {@link java.rmi.server.UID UID} instance) as the argument.
 *
 * <p>Next, the {@link
 * java.rmi.server.RemoteRef#getRefClass(java.io.ObjectOutput)
 * getRefClass} method is invoked on the activator's
 * <code>RemoteRef</code> instance to obtain its external ref
 * type name.  Next, the <code>writeUTF</code> method is
 * invoked on <code>out</code> with the value returned by
 * <code>getRefClass</code>, and then the
 * <code>writeExternal</code> method is invoked on the
 * <code>RemoteRef</code> instance passing <code>out</code>
 * as the argument.
 *
 * @serialData The serialized data for this class comprises a
 * <code>java.rmi.server.UID</code> (written with
 * <code>ObjectOutput.writeObject</code>) followed by the
 * external ref type name of the activator's
 * <code>RemoteRef</code> instance (a string written with
 * <code>ObjectOutput.writeUTF</code>), followed by the
 * external form of the <code>RemoteRef</code> instance as
 * written by its <code>writeExternal</code> method.
 *
 * <p>The external ref type name of the
 * <code>RemoteRef</Code> instance is
 * determined using the definitions of external ref type
 * names specified in the {@link java.rmi.server.RemoteObject
 * RemoteObject} <code>writeObject</code> method
 * <b>serialData</b> specification.  Similarly, the data
 * written by the <code>writeExternal</code> method and read
 * by the <code>readExternal</code> method of
 * <code>RemoteRef</code> implementation classes
 * corresponding to each of the defined external ref type
 * names is specified in the {@link
 * java.rmi.server.RemoteObject RemoteObject}
 * <code>writeObject</code> method <b>serialData</b>
 * specification.
 **/
private void writeObject(ObjectOutputStream out)
    throws IOException, ClassNotFoundException
{
    out.writeObject(uid);

    RemoteRef ref;
    if (activator instanceof RemoteObject) {
        ref = ((RemoteObject) activator).getRef();
    } else if (Proxy.isProxyClass(activator.getClass())) {
        InvocationHandler handler = Proxy.getInvocationHandler(activator);
        if (!(handler instanceof RemoteObjectInvocationHandler)) {
            throw new InvalidObjectException(
                "unexpected invocation handler");
        }
        ref = ((RemoteObjectInvocationHandler) handler).getRef();

    } else {
        throw new InvalidObjectException("unexpected activator type");
    }
    out.writeUTF(ref.getRefClass(out));
    ref.writeExternal(out);
}
 
源代码17 项目: TencentKona-8   文件: UseDynamicProxies.java
public static void main(String[] args) throws Exception {

        RemoteInterface server = null;
        RemoteInterface proxy = null;

        try {
            System.setProperty("java.rmi.server.ignoreStubClasses", args[0]);
            boolean ignoreStubClasses = Boolean.parseBoolean(args[0]);

            if (System.getSecurityManager() == null) {
                System.setSecurityManager(new SecurityManager());
            }

            System.err.println("export object");
            server = new UseDynamicProxies();
            proxy =
                (RemoteInterface) UnicastRemoteObject.exportObject(server, 0);

            System.err.println("proxy = " + proxy);
            if (ignoreStubClasses) {
                if (!Proxy.isProxyClass(proxy.getClass())) {
                    throw new RuntimeException(
                        "server proxy is not a dynamic proxy");
                }
                if (!(Proxy.getInvocationHandler(proxy) instanceof
                      RemoteObjectInvocationHandler))
                {
                    throw new RuntimeException("invalid invocation handler");
                }

            } else if (!(proxy instanceof RemoteStub)) {
                throw new RuntimeException(
                    "server proxy is not a RemoteStub");
            }

            System.err.println("invoke methods");
            Object obj = proxy.passObject(proxy);
            if (!proxy.equals(obj)) {
                throw new RuntimeException("returned proxy not equal");
            }

            int x = proxy.passInt(53);
            if (x != 53) {
                throw new RuntimeException("returned int not equal");
            }

            String string = proxy.passString("test");
            if (!string.equals("test")) {
                throw new RuntimeException("returned string not equal");
            }

            System.err.println("TEST PASSED");

        } finally {
            if (proxy != null) {
                UnicastRemoteObject.unexportObject(server, true);
            }
        }
    }
 
源代码18 项目: TencentKona-8   文件: MBSFPreStartPostStartTest.java
/**
 * Run test
 */
public int runTest(boolean setBeforeStart) throws Exception {

    echo("=-=-= MBSFPreStartPostStartTest: Set MBSF " +
         (setBeforeStart ? "before" : "after") +
         " starting the connector server =-=-=");

    JMXConnectorServer server = null;
    JMXConnector client = null;

    // Create a new MBeanServer
    //
    final MBeanServer mbs = MBeanServerFactory.createMBeanServer();

    try {
        // Create the JMXServiceURL
        //
        final JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");

        // Create a JMXConnectorServer
        //
        server = JMXConnectorServerFactory.newJMXConnectorServer(url,
                                                                 null,
                                                                 mbs);

        // Create MBeanServerForwarder
        //
        MBeanServerForwarder mbsf =
            MBSFInvocationHandler.newProxyInstance();

        // Set MBeanServerForwarder before start()
        //
        if (setBeforeStart)
            server.setMBeanServerForwarder(mbsf);

        // Start the JMXConnectorServer
        //
        server.start();

        // Set MBeanServerForwarder after start()
        //
        if (!setBeforeStart)
            server.setMBeanServerForwarder(mbsf);

        // Create a JMXConnector
        //
        client = server.toJMXConnector(null);

        // Connect to the connector server
        //
        client.connect(null);

        // Get non-secure MBeanServerConnection
        //
        final MBeanServerConnection mbsc =
            client.getMBeanServerConnection();

        // Run method
        //
        mbsc.getDefaultDomain();

        // Check flag in MBeanServerForwarder
        //
        MBSFInvocationHandler mbsfih =
            (MBSFInvocationHandler) Proxy.getInvocationHandler(mbsf);
        if (mbsfih.getFlag() == true) {
            echo("OK: Did go into MBeanServerForwarder!");
        } else {
            echo("KO: Didn't go into MBeanServerForwarder!");
            return 1;
        }
    } catch (Exception e) {
        echo("Failed to perform operation: " + e);
        return 1;
    } finally {
        // Close the connection
        //
        if (client != null)
            client.close();

        // Stop the connector server
        //
        if (server != null)
            server.stop();

        // Release the MBeanServer
        //
        if (mbs != null)
            MBeanServerFactory.releaseMBeanServer(mbs);
    }

    return 0;
}
 
源代码19 项目: dragonwell8_jdk   文件: ActivationID.java
/**
 * <code>writeObject</code> for custom serialization.
 *
 * <p>This method writes this object's serialized form for
 * this class as follows:
 *
 * <p>The <code>writeObject</code> method is invoked on
 * <code>out</code> passing this object's unique identifier
 * (a {@link java.rmi.server.UID UID} instance) as the argument.
 *
 * <p>Next, the {@link
 * java.rmi.server.RemoteRef#getRefClass(java.io.ObjectOutput)
 * getRefClass} method is invoked on the activator's
 * <code>RemoteRef</code> instance to obtain its external ref
 * type name.  Next, the <code>writeUTF</code> method is
 * invoked on <code>out</code> with the value returned by
 * <code>getRefClass</code>, and then the
 * <code>writeExternal</code> method is invoked on the
 * <code>RemoteRef</code> instance passing <code>out</code>
 * as the argument.
 *
 * @serialData The serialized data for this class comprises a
 * <code>java.rmi.server.UID</code> (written with
 * <code>ObjectOutput.writeObject</code>) followed by the
 * external ref type name of the activator's
 * <code>RemoteRef</code> instance (a string written with
 * <code>ObjectOutput.writeUTF</code>), followed by the
 * external form of the <code>RemoteRef</code> instance as
 * written by its <code>writeExternal</code> method.
 *
 * <p>The external ref type name of the
 * <code>RemoteRef</Code> instance is
 * determined using the definitions of external ref type
 * names specified in the {@link java.rmi.server.RemoteObject
 * RemoteObject} <code>writeObject</code> method
 * <b>serialData</b> specification.  Similarly, the data
 * written by the <code>writeExternal</code> method and read
 * by the <code>readExternal</code> method of
 * <code>RemoteRef</code> implementation classes
 * corresponding to each of the defined external ref type
 * names is specified in the {@link
 * java.rmi.server.RemoteObject RemoteObject}
 * <code>writeObject</code> method <b>serialData</b>
 * specification.
 **/
private void writeObject(ObjectOutputStream out)
    throws IOException, ClassNotFoundException
{
    out.writeObject(uid);

    RemoteRef ref;
    if (activator instanceof RemoteObject) {
        ref = ((RemoteObject) activator).getRef();
    } else if (Proxy.isProxyClass(activator.getClass())) {
        InvocationHandler handler = Proxy.getInvocationHandler(activator);
        if (!(handler instanceof RemoteObjectInvocationHandler)) {
            throw new InvalidObjectException(
                "unexpected invocation handler");
        }
        ref = ((RemoteObjectInvocationHandler) handler).getRef();

    } else {
        throw new InvalidObjectException("unexpected activator type");
    }
    out.writeUTF(ref.getRefClass(out));
    ref.writeExternal(out);
}
 
/**
 * Processes a method invocation made on the encapsulating
 * proxy instance, <code>proxy</code>, and returns the result.
 *
 * <p><code>RemoteObjectInvocationHandler</code> implements this method
 * as follows:
 *
 * <p>If <code>method</code> is one of the following methods, it
 * is processed as described below:
 *
 * <ul>
 *
 * <li>{@link Object#hashCode Object.hashCode}: Returns the hash
 * code value for the proxy.
 *
 * <li>{@link Object#equals Object.equals}: Returns <code>true</code>
 * if the argument (<code>args[0]</code>) is an instance of a dynamic
 * proxy class and this invocation handler is equal to the invocation
 * handler of that argument, and returns <code>false</code> otherwise.
 *
 * <li>{@link Object#toString Object.toString}: Returns a string
 * representation of the proxy.
 * </ul>
 *
 * <p>Otherwise, a remote call is made as follows:
 *
 * <ul>
 * <li>If <code>proxy</code> is not an instance of the interface
 * {@link Remote}, then an {@link IllegalArgumentException} is thrown.
 *
 * <li>Otherwise, the {@link RemoteRef#invoke invoke} method is invoked
 * on this invocation handler's <code>RemoteRef</code>, passing
 * <code>proxy</code>, <code>method</code>, <code>args</code>, and the
 * method hash (defined in section 8.3 of the "Java Remote Method
 * Invocation (RMI) Specification") for <code>method</code>, and the
 * result is returned.
 *
 * <li>If an exception is thrown by <code>RemoteRef.invoke</code> and
 * that exception is a checked exception that is not assignable to any
 * exception in the <code>throws</code> clause of the method
 * implemented by the <code>proxy</code>'s class, then that exception
 * is wrapped in an {@link UnexpectedException} and the wrapped
 * exception is thrown.  Otherwise, the exception thrown by
 * <code>invoke</code> is thrown by this method.
 * </ul>
 *
 * <p>The semantics of this method are unspecified if the
 * arguments could not have been produced by an instance of some
 * valid dynamic proxy class containing this invocation handler.
 *
 * @param proxy the proxy instance that the method was invoked on
 * @param method the <code>Method</code> instance corresponding to the
 * interface method invoked on the proxy instance
 * @param args an array of objects containing the values of the
 * arguments passed in the method invocation on the proxy instance, or
 * <code>null</code> if the method takes no arguments
 * @return the value to return from the method invocation on the proxy
 * instance
 * @throws  Throwable the exception to throw from the method invocation
 * on the proxy instance
 **/
public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable
{
    if (! Proxy.isProxyClass(proxy.getClass())) {
        throw new IllegalArgumentException("not a proxy");
    }

    if (Proxy.getInvocationHandler(proxy) != this) {
        throw new IllegalArgumentException("handler mismatch");
    }

    if (method.getDeclaringClass() == Object.class) {
        return invokeObjectMethod(proxy, method, args);
    } else if ("finalize".equals(method.getName()) && method.getParameterCount() == 0 &&
        !allowFinalizeInvocation) {
        return null; // ignore
    } else {
        return invokeRemoteMethod(proxy, method, args);
    }
}