proxy
, and returns the result. This method is invoked when a method is invoked on a proxy instance that this handler is associated with. BasicInvocationHandler
implements this method as follows:
If method
is one of the following methods, it is processed as described below:
true
if the argument (args[0]
) is an instance of a dynamic proxy class that implements the same ordered set of interfaces as proxy
and this invocation handler is equal to the invocation handler of that argument, and returns false
otherwise. proxy
containing a new invocation handler with the specified new client constraints. The new invocation handler is created by invoking the {@link #setClientConstraints setClientConstraints} methodof this object with the specified client constraints (args[0]
). An exception is thrown if proxy
is not an instance of a dynamic proxy class containing this invocation handler. BasicInvocationHandler
's client constraints. true
if the argument (args[0]
) is an instance of a dynamic proxy class that implements the same ordered set of interfaces as proxy
and invoking the {@link #checkTrustEquivalence checkTrustEquivalence} methodof this object with the invocation handler of that argument returns true
, and returns false
otherwise. Otherwise, a remote call is made as follows:
The object endpoint's {@link ObjectEndpoint#newCall newCall}method is invoked to obtain an {@link OutboundRequestIterator}, passing constraints obtained by combining the client and server constraints for the specified remote method and making them absolute. If the returned iterator's {@link OutboundRequestIterator#hasNext hasNext} method returnsfalse
, then this method throws a {@link ConnectIOException}. Otherwise, the iterator is used to make one or more attempts to communicate the remote call. Each attempt proceeds as follows:
The iterator's {@link OutboundRequestIterator#next next} methodis invoked to obtain an {@link OutboundRequest OutboundRequest}for the current attempt. Ifnext
returns normally, the request's {@link OutboundRequest#getUnfulfilledConstraints getUnfulfilledConstraints} method is invoked, and if thereturned requirements or preferences include {@link Integrity#YES Integrity.YES}, object integrity is enforced for the current remote call attempt. If the returned requirements include any constraint other than an {@link Integrity}constraint, an {@link UnsupportedConstraintException} isgenerated and, as described below, wrapped and handled like any otherException
thrown from a remote call attempt. Otherwise, the marshalling of the remote call proceeds with the following steps in order:
- A byte of value
0x00
is written to the request output stream of theOutboundRequest
to indicate the version of the marshalling protocol being used.- A byte is written to specify object integrity enforcement:
0x01
if object integrity is being enforced for this remote call attempt, and0x00
otherwise.- A client context collection is created containing an {@link IntegrityEnforcement} element that reflects whether or notobject integrity is being enforced for this remote call attempt.
- The {@link #createMarshalOutputStream createMarshalOutputStream} method is invoked, passing
proxy
,method
, theOutboundRequest
, and the client context, to create the marshal output stream for marshalling the remote call.- The {@link #marshalMethod marshalMethod} method of thisinvocation handler is invoked with
proxy
,method
, the marshal output stream, and the client context.- The {@link #marshalArguments marshalArguments} method ofthis invocation handler is invoked with
proxy
,method
,args
, the marshal output stream, and the client context.- The marshal output stream is closed.
Then the object endpoint's {@link ObjectEndpoint#executeCall executeCall} method is invoked with the
OutboundRequest
. IfexecuteCall
returns aRemoteException
, then this method throws that exception (and thus the remote call attempt iteration terminates). IfexecuteCall
returnsnull
, then the unmarshalling of the call response proceeds as follows:A byte is read from the response input stream of the
OutboundRequest
:
- If the byte is
0x00
, indicating a marshalling protocol version mismatch, a {@link ProtocolException} isgenerated and, as described below, wrapped and handled like any otherException
thrown from a remote call attempt.- If the byte is
0x01
, indicating a normal return, the {@link #createMarshalInputStream createMarshalInputStream} method is invoked, passingproxy
,method
, theOutboundRequest
, aboolean
indicating whether or not object integrity is being enforced, and the client context, to create the marshal input stream for unmarshalling the response, and the {@link #unmarshalReturn unmarshalReturn} method of this invocation handler is invokedwithproxy
,method
, the marshal input stream, and the client context. This method returns the value returned byunmarshalReturn
(and thus the remote call attempt iteration terminates).- If the byte is
0x02
, indicating an exceptional return, a marshal input stream is created by calling thecreateMarshalInputStream
method as described for the previous case, and the {@link #unmarshalThrow unmarshalThrow} method of this invocation handler is invokedwithproxy
,method
, the marshal input stream, and the client context. This method throws the exception returned byunmarshalThrow
(and thus the remote call attempt iteration terminates).- If the byte is any other value, a
ProtocolException
is generated and, as described below, wrapped and handled like any otherException
thrown from a remote call attempt.If an
IOException
is thrown during the attempt to communicate the remote call, then it is wrapped in aRemoteException
as follows:
- If
marshalMethod
was not invoked for this attempt, or if an invocation of {@link OutboundRequest#getDeliveryStatus getDeliveryStatus} on theOutboundRequest
returnsfalse
, or if a marshalling protocol version mismatch was detected, then
- if the
IOException
is a {@link java.net.UnknownHostException java.net.UnknownHostException}, it is wrapped in a {@link java.rmi.UnknownHostException java.rmi.UnknownHostException};- if it is a {@link java.net.ConnectException java.net.ConnectException}, it is wrapped in a {@link java.rmi.ConnectException java.rmi.ConnectException};
- if it is any other
IOException
, it is wrapped in a {@link ConnectIOException}.- Otherwise, if
executeCall
was not invoked for this attempt, theIOException
is wrapped in a {@link MarshalException}, and ifexecuteCall
was invoked, it is wrapped in an {@link UnmarshalException}.If a {@link ClassNotFoundException} is thrownduring the unmarshalling, then it is wrapped in an {@link UnmarshalException}.
In all cases, either the request output stream and the response input stream will be closed or the
OutboundRequest
will be aborted before this attempt completes.
If an attempt to communicate the remote call throws an Exception
(other than an exception returned by executeCall
or unmarshalThrow
, which terminates the remote call attempt iteration), then if marshalMethod
was not invoked for the attempt or if an invocation of getDeliveryStatus
on the OutboundRequest
returns false
, then if the iterator's hasNext
method returns true
, then another attempt is made. Otherwise, this method throws the Exception
thrown by the last attempt (possibly wrapped as described above).
Note that invoking a remote method on a remote object via this invoke method preserves "at-most-once" call semantics. At-most-once call semantics guarantees that the remote call will either a) not execute, b) partially execute, or c) execute exactly once at the remote site. With Java RMI's at-most-once call semantics, arguments may be marshalled more than once for a given remote call.
A subclass can override this method to handle the methods of any additional non-remote interfaces implemented by the proxy or to otherwise control invocation handling behavior.
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. This method throws {@link IllegalArgumentException} ifproxy
is an instance of InvocationHandler
or, if a remote call is to be made, any of the superinterfaces of proxy
's class have a method with the same name and parameter types as method
but that does not declare RemoteException
or a superclass of RemoteException
in its throws
clause (even if such a method is not a member of any of the direct superinterfaces of proxy
's class because of overriding).
@throws Throwable {@inheritDoc}
@see java.lang.reflect.UndeclaredThrowableException
|
|