RemoteObjectInvocationHandlerpublic class RemoteObjectInvocationHandler extends RemoteObject implements InvocationHandlerAn implementation of the InvocationHandler interface for
use with Java Remote Method Invocation (Java RMI). This invocation
handler can be used in conjunction with a dynamic proxy instance as a
replacement for a pregenerated stub class.
Applications are not expected to use this class directly. A remote
object exported to use a dynamic proxy with {@link UnicastRemoteObject}
or {@link Activatable} has an instance of this class as that proxy's
invocation handler. |
Fields Summary |
---|
private static final long | serialVersionUID | private static final MethodToHash_Maps | methodToHash_MapsA weak hash map, mapping classes to weak hash maps that map
method objects to method hashes. |
Constructors Summary |
---|
public RemoteObjectInvocationHandler(RemoteRef ref)Creates a new RemoteObjectInvocationHandler constructed
with the specified RemoteRef .
super(ref);
if (ref == null) {
throw new NullPointerException();
}
|
Methods Summary |
---|
private static long | getMethodHash(java.lang.reflect.Method method)Returns the method hash for the specified method. Subsequent calls
to "getMethodHash" passing the same method argument should be faster
since this method caches internally the result of the method to
method hash mapping. The method hash is calculated using the
"computeMethodHash" method.
Map map = methodToHash_Maps.getMap(method.getDeclaringClass());
Long hash = (Long) map.get(method);
return hash.longValue();
| public java.lang.Object | invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)Processes a method invocation made on the encapsulating
proxy instance, proxy , and returns the result.
RemoteObjectInvocationHandler implements this method
as follows:
If method is one of the following methods, it
is processed as described below:
- {@link Object#hashCode Object.hashCode}: Returns the hash
code value for the proxy.
- {@link Object#equals Object.equals}: Returns
true
if the argument (args[0] ) is an instance of a dynamic
proxy class and this invocation handler is equal to the invocation
handler of that argument, and returns false otherwise.
- {@link Object#toString Object.toString}: Returns a string
representation of the proxy.
Otherwise, a remote call is made as follows:
- If
proxy is not an instance of the interface
{@link Remote}, then an {@link IllegalArgumentException} is thrown.
- Otherwise, the {@link RemoteRef#invoke invoke} method is invoked
on this invocation handler's
RemoteRef , passing
proxy , method , args , and the
method hash (defined in section 8.3 of the "Java Remote Method
Invocation (RMI) Specification") for method , and the
result is returned.
- If an exception is thrown by
RemoteRef.invoke and
that exception is a checked exception that is not assignable to any
exception in the throws clause of the method
implemented by the proxy 's class, then that exception
is wrapped in an {@link UnexpectedException} and the wrapped
exception is thrown. Otherwise, the exception thrown by
invoke is thrown by this method.
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.
if (method.getDeclaringClass() == Object.class) {
return invokeObjectMethod(proxy, method, args);
} else {
return invokeRemoteMethod(proxy, method, args);
}
| private java.lang.Object | invokeObjectMethod(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)Handles java.lang.Object methods.
String name = method.getName();
if (name.equals("hashCode")) {
return new Integer(hashCode());
} else if (name.equals("equals")) {
Object obj = args[0];
boolean b =
proxy == obj ||
(obj != null &&
Proxy.isProxyClass(obj.getClass()) &&
equals(Proxy.getInvocationHandler(obj)));
return Boolean.valueOf(b);
} else if (name.equals("toString")) {
return proxyToString(proxy);
} else {
throw new IllegalArgumentException(
"unexpected Object method: " + method);
}
| private java.lang.Object | invokeRemoteMethod(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)Handles remote methods.
try {
if (!(proxy instanceof Remote)) {
throw new IllegalArgumentException(
"proxy not Remote instance");
}
return ref.invoke((Remote) proxy, method, args,
getMethodHash(method));
} catch (Exception e) {
if (!(e instanceof RuntimeException)) {
Class cl = proxy.getClass();
try {
method = cl.getMethod(method.getName(),
method.getParameterTypes());
} catch (NoSuchMethodException nsme) {
throw (IllegalArgumentException)
new IllegalArgumentException().initCause(nsme);
}
Class[] exTypes = method.getExceptionTypes();
Class thrownType = e.getClass();
for (int i = 0; i < exTypes.length; i++) {
if (exTypes[i].isAssignableFrom(thrownType)) {
throw e;
}
}
e = new UnexpectedException("unexpected exception", e);
}
throw e;
}
| private java.lang.String | proxyToString(java.lang.Object proxy)Returns a string representation for a proxy that uses this invocation
handler.
Class[] interfaces = proxy.getClass().getInterfaces();
if (interfaces.length == 0) {
return "Proxy[" + this + "]";
}
String iface = interfaces[0].getName();
if (iface.equals("java.rmi.Remote") && interfaces.length > 1) {
iface = interfaces[1].getName();
}
int dot = iface.lastIndexOf('.");
if (dot >= 0) {
iface = iface.substring(dot + 1);
}
return "Proxy[" + iface + "," + this + "]";
| private void | readObjectNoData()
throw new InvalidObjectException("no data in stream; class: " +
this.getClass().getName());
|
|