public class BasicInvocationHandler extends Object implements InvocationHandler, TrustEquivalence, Serializable
InvocationHandler
interface.
This invocation handler implements Java(TM) Remote Method Invocation
(Java RMI) call semantics when handling
a remote invocation to a remote object.
BasicInvocationHandler
instances contain an
ObjectEndpoint
, optional client constraints, and
optional server constraints. The client and server constraints
control the handling of remote methods, and they are represented as
MethodConstraints
objects that map remote methods to
corresponding per-method constraints.
Invocation requests sent via the invoke
method use
the protocol defined in that method. This invocation handler also
assumes that the return value conforms to the protocol outlined in the
BasicInvocationDispatcher.dispatch
method.
BasicInvocationDispatcher
,
Serialized Forminvoke
method throws IllegalArgumentException
if a remote invocation is to be made and
the proxy
argument is an instance of an interface
whose binary name is
javax.management.MBeanServerConnection
or any of the
names produced by the following procedure:
For each resource named
org/apache/river/proxy/resources/InvocationHandler.moreProhibitedProxyInterfaces
that is visible to the system class loader, the contents of the
resource are parsed as UTF-8 text to produce a list of interface
names. The resource must contain a list of binary names of
interfaces, one per line. Space and tab characters surrounding
each name, as well as blank lines, are ignored. The comment
character is '#'; on each line, all characters starting
with the first comment character are ignored.
This implementation uses the Logger
named
net.jini.jeri.BasicInvocationHandler
to log
information at the following levels:
Level | Description |
---|---|
FAILED | exception thrown from final attempt to communicate a remote call |
HANDLED | exception caught in attempt to communicate a remote call |
FINE | remote method being invoked |
FINE | successful return of remote call |
FINEST | more detailed information on the above (for example, actual argument and return values) |
Constructor and Description |
---|
BasicInvocationHandler(BasicInvocationHandler other,
MethodConstraints clientConstraints)
Creates a new
BasicInvocationHandler with the
specified client constraints and with the same
ObjectEndpoint and server constraints as the given
other BasicInvocationHandler . |
BasicInvocationHandler(ObjectEndpoint oe,
MethodConstraints serverConstraints)
Creates a new
BasicInvocationHandler with the
specified ObjectEndpoint and server constraints. |
Modifier and Type | Method and Description |
---|---|
boolean |
checkTrustEquivalence(Object obj)
Returns
true if the specified object (which is not
yet known to be trusted) is equivalent in trust, content, and
function to this known trusted object, and false
otherwise. |
protected ObjectInputStream |
createMarshalInputStream(Object proxy,
Method method,
OutboundRequest request,
boolean integrity,
Collection context)
Returns a new
ObjectInputStream instance to use to read
objects from the response input stream obtained by invoking the getResponseInputStream method
on the given request . |
protected ObjectOutputStream |
createMarshalOutputStream(Object proxy,
Method method,
OutboundRequest request,
Collection context)
Returns a new
ObjectOutputStream instance to use to write
objects to the request output stream obtained by invoking the getRequestOutputStream method
on the given request . |
boolean |
equals(Object obj)
Compares the specified object with this
BasicInvocationHandler for equality. |
MethodConstraints |
getClientConstraints()
Returns this
BasicInvocationHandler 's client
constraints. |
ObjectEndpoint |
getObjectEndpoint()
Returns this
BasicInvocationHandler 's
ObjectEndpoint . |
MethodConstraints |
getServerConstraints()
Returns this
BasicInvocationHandler 's server
constraints. |
int |
hashCode()
Returns the hash code value for this invocation handler.
|
Object |
invoke(Object proxy,
Method method,
Object[] args)
Processes a method invocation made on the encapsulating
proxy instance,
proxy , and returns the result. |
protected void |
marshalArguments(Object proxy,
Method method,
Object[] args,
ObjectOutputStream out,
Collection context)
Marshals the arguments for the specified remote method to the outgoing
request stream,
out . |
protected void |
marshalMethod(Object proxy,
Method method,
ObjectOutputStream out,
Collection context)
Marshals a representation of the given
method to
the outgoing request stream, out . |
protected InvocationHandler |
setClientConstraints(MethodConstraints constraints)
Returns a copy of this invocation handler with the specified
constraints as its new client constraints.
|
String |
toString()
Returns a string representation of this
BasicInvocationHandler . |
protected Object |
unmarshalReturn(Object proxy,
Method method,
ObjectInputStream in,
Collection context)
Unmarshals the return value for the specified remote method from the
incoming response stream,
in . |
protected Throwable |
unmarshalThrow(Object proxy,
Method method,
ObjectInputStream in,
Collection context)
Unmarshals the throwable for the specified remote method from the
incoming response stream,
in , and returns the result. |
public BasicInvocationHandler(ObjectEndpoint oe, MethodConstraints serverConstraints)
BasicInvocationHandler
with the
specified ObjectEndpoint
and server constraints.
The client constraints of the created
BasicInvocationHandler
will be null
.
oe
- the ObjectEndpoint
for this invocation handlerserverConstraints
- the server constraints, or null
NullPointerException
- if oe
is null
public BasicInvocationHandler(BasicInvocationHandler other, MethodConstraints clientConstraints)
BasicInvocationHandler
with the
specified client constraints and with the same
ObjectEndpoint
and server constraints as the given
other BasicInvocationHandler
.
This constructor is intended for use by the
BasicInvocationHandler
implementation of the
setClientConstraints(net.jini.core.constraint.MethodConstraints)
method. To create a copy of a
given BasicInvocationHandler
with new client
constraints, use the RemoteMethodControl.setConstraints
method on the containing
proxy.
other
- the BasicInvocationHandler
to obtain the
ObjectEndpoint
and server constraints fromclientConstraints
- the client constraints, or
null
NullPointerException
- if other
is
null
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
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:
Object.hashCode
: Returns the hash
code value for the proxy.
Object.equals
: Returns
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.
Object.toString
: Returns a string
representation of the proxy.
RemoteMethodControl.setConstraints
: Returns a new proxy
instance of the same class as proxy
containing a
new invocation handler with the specified new client
constraints. The new invocation handler is created by invoking
the setClientConstraints
method
of 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.
RemoteMethodControl.getConstraints
: Returns this
BasicInvocationHandler
's client constraints.
TrustEquivalence.checkTrustEquivalence
: Returns
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 checkTrustEquivalence
method
of 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 newCall
method is invoked to obtain an 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 hasNext
method returns
false
, then this method throws a ConnectIOException
. Otherwise, the iterator is used to make
one or more attempts to communicate the remote call. Each
attempt proceeds as follows:
The iterator'snext
method is invoked to obtain anOutboundRequest
for the current attempt. Ifnext
returns normally, the request'sgetUnfulfilledConstraints
method is invoked, and if the returned requirements or preferences includeIntegrity.YES
, object integrity is enforced for the current remote call attempt. If the returned requirements include any constraint other than anIntegrity
constraint, anUnsupportedConstraintException
is generated 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
IntegrityEnforcement
element that reflects whether or not object integrity is being enforced for this remote call attempt.- The
createMarshalOutputStream
method is invoked, passingproxy
,method
, theOutboundRequest
, and the client context, to create the marshal output stream for marshalling the remote call.- The
marshalMethod
method of this invocation handler is invoked withproxy
,method
, the marshal output stream, and the client context.- The
marshalArguments
method of this invocation handler is invoked withproxy
,method
,args
, the marshal output stream, and the client context.- The marshal output stream is closed.
Then the object endpoint's
executeCall
method is invoked with theOutboundRequest
. 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, aProtocolException
is generated 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, thecreateMarshalInputStream
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 theunmarshalReturn
method of this invocation handler is invoked withproxy
,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 theunmarshalThrow
method of this invocation handler is invoked withproxy
,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 ofgetDeliveryStatus
on theOutboundRequest
returnsfalse
, or if a marshalling protocol version mismatch was detected, then
- if the
IOException
is ajava.net.UnknownHostException
, it is wrapped in ajava.rmi.UnknownHostException
;- if it is a
java.net.ConnectException
, it is wrapped in ajava.rmi.ConnectException
;- if it is any other
IOException
, it is wrapped in aConnectIOException
.- Otherwise, if
executeCall
was not invoked for this attempt, theIOException
is wrapped in aMarshalException
, and ifexecuteCall
was invoked, it is wrapped in anUnmarshalException
.If a
ClassNotFoundException
is thrown during the unmarshalling, then it is wrapped in anUnmarshalException
.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 IllegalArgumentException
if
proxy
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).
invoke
in interface InvocationHandler
Throwable
UndeclaredThrowableException
protected InvocationHandler setClientConstraints(MethodConstraints constraints)
BasicInvocationHandler
implements this method
as follows:
This method looks for a public constructor declared by the
class of this object with two parameters, the first parameter
type being the class of this object and the second parameter
type being MethodConstraints
. If found, the
constructor is invoked with this instance and the specified
constraints, and the resulting object is returned. If the
constructor could not be found or was not accessible, or if the
constructor invocation throws an exception, an
UndeclaredThrowableException
is thrown.
A subclass can override this method to control how the invocation handler is copied.
constraints
- the new client constraints, or
null
protected ObjectOutputStream createMarshalOutputStream(Object proxy, Method method, OutboundRequest request, Collection context) throws IOException
ObjectOutputStream
instance to use to write
objects to the request output stream obtained by invoking the getRequestOutputStream
method
on the given request
.
BasicInvocationHandler
implements this method
to return a new MarshalOutputStream
instance
constructed with the output stream obtained from
request
as specified above and an unmodifiable
view of the supplied context
collection.
A subclass can override this method to control how the marshal input stream is created or implemented.
proxy
- the proxy instancemethod
- the remote method invokedrequest
- the outbound requestcontext
- the client contextObjectOutputStream
instance for marshalling
a call requestIOException
- if an I/O exception occursNullPointerException
- if any argument is null
protected ObjectInputStream createMarshalInputStream(Object proxy, Method method, OutboundRequest request, boolean integrity, Collection context) throws IOException
ObjectInputStream
instance to use to read
objects from the response input stream obtained by invoking the getResponseInputStream
method
on the given request
.
BasicInvocationHandler
implements this method
to return a new MarshalInputStream
instance constructed
with the input stream obtained from request
as
specified above for the input stream in
, the class
loader of proxy
's class for
defaultLoader
and verifierLoader
,
this method's integrity
argument for
verifyCodebaseIntegrity
, and an unmodifiable view
of context
for the context
collection. The useCodebaseAnnotations
method is invoked on the created stream
before it is returned.
An exception is thrown if proxy
is not an instance
of a dynamic proxy class containing this invocation handler.
A subclass can override this method to control how the marshal input stream is created or implemented.
proxy
- the proxy instancemethod
- the remote method invokedrequest
- the outbound requestintegrity
- whether or not to verify codebase integritycontext
- the client contextObjectInputStream
instance for unmarshalling
a call responseIOException
- if an I/O exception occursNullPointerException
- if any argument is null
protected void marshalMethod(Object proxy, Method method, ObjectOutputStream out, Collection context) throws IOException
method
to
the outgoing request stream, out
. For each remote
call, the invoke
method calls this method to
marshal a representation of the method.
BasicInvocationHandler
implements this method
to write the JRMP method hash (defined in section 8.3 of the
Java RMI specification) for the given method to the output stream
using the writeLong
method.
A subclass can override this method to control how the remote method is marshalled.
proxy
- the proxy instance that the method was invoked onmethod
- the Method
instance corresponding
to the interface method invoked on the proxy
instance. The declaring class of the
Method
object will be the interface that
the method was declared in, which may be a
superinterface of the proxy interface that the proxy
class inherits the method through.out
- outgoing request stream for the remote callcontext
- the client contextIOException
- if an I/O exception occursNullPointerException
- if any argument is null
protected void marshalArguments(Object proxy, Method method, Object[] args, ObjectOutputStream out, Collection context) throws IOException
out
. For each remote call, the
invoke
method calls this method to marshal arguments.
BasicInvocationHandler
implements this method
marshal each argument as follows:
If the corresponding declared parameter type is primitive, then the
the primitive value is written to the stream (for example, if the type
is int.class
, then the primitive int
value
is written to the stream using the writeInt
method).
Otherwise, the argument is written to the stream using the
writeObject
method.
A subclass can override this method to marshal the arguments in an alternative context, perform pre- or post-processing on the arguments, marshal additional implicit data, or otherwise control how the arguments are marshalled.
proxy
- the proxy instance that the method was invoked onmethod
- the Method
instance corresponding
to the interface method invoked on the proxy
instance. The declaring class of the
Method
object will be the interface that
the method was declared in, which may be a
superinterface of the proxy interface that the proxy
class inherits the method through.args
- an array of objects containing the values of the
arguments passed in the method invocation on the
proxy instance. If an argument's corresponding declared
parameter type is primitive, then its value is
represented with an instance of the corresponding primitive
wrapper class, such as java.lang.Integer
or
java.lang.Boolean
.out
- outgoing request stream for the remote callcontext
- the client contextIOException
- if an I/O exception occursNullPointerException
- if any argument is null
protected Object unmarshalReturn(Object proxy, Method method, ObjectInputStream in, Collection context) throws IOException, ClassNotFoundException
in
. In the case that a value is
returned from the invocation on the remote object, this method is
called to unmarshal that return value.
BasicInvocationHandler
implements this method
as follows:
If the return type of the method is void, then no return value is
read from the stream and null
is returned. If the return
type is a primitive type, then the primitive value is read from the
stream (for example, if the type is int.class
, then the
primitive int
value is read from the stream using the
readInt
method). Otherwise, the return value is read from
the stream using the readObject
method.
A subclass can override this method to unmarshal the return value in an alternative context, perform post-processing on the return value, unmarshal additional implicit data, or otherwise control how the return value is unmarshalled.
proxy
- the proxy instance that the method was invoked onmethod
- the Method
instance corresponding
to the interface method invoked on the proxy
instance. The declaring class of the
Method
object will be the interface that
the method was declared in, which may be a
superinterface of the proxy interface that the proxy
class inherits the method through.in
- the incoming result stream for the remote callcontext
- the client contextinvoke
will be an
instance of the corresponding primitive wrapper
class; otherwise, it will be a type assignable to
the declared return type.IOException
- if an I/O exception occursClassNotFoundException
- if a class could not be found during
unmarshallingNullPointerException
- if any argument is null
protected Throwable unmarshalThrow(Object proxy, Method method, ObjectInputStream in, Collection context) throws IOException, ClassNotFoundException
in
, and returns the result. In
the case that an exception was thrown as a result of the
invocation on the remote object, this method is called to unmarshal
that throwable.
BasicInvocationHandler
implements this method
to return the throwable unmarshalled from the stream using the
readObject
method. If the unmarshalled throwable
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: if there is no public member
method of proxy
's class with the same name and
parameter types as method
an IllegalArgumentException
is thrown, otherwise that exception
is wrapped in an UnexpectedException
and the wrapped
exception is returned.
A subclass can override this method to unmarshal the return value in an alternative context, perform post-processing on the return value, unmarshal additional implicit data, or otherwise control how the return value is unmarshalled.
proxy
- the proxy instance that the method was invoked onmethod
- the Method
instance corresponding
to the interface method invoked on the proxy
instance. The declaring class of the
Method
object will be the interface that
the method was declared in, which may be a
superinterface of the proxy interface that the proxy
class inherits the method through.context
- the client contextin
- the incoming result stream for the remote callthrows
clause of the interface
method or to the unchecked exception types
java.lang.RuntimeException
or
java.lang.Error
.IOException
- if an I/O exception occursClassNotFoundException
- if a class could not be found during
unmarshallingNullPointerException
- if any argument is null
public final ObjectEndpoint getObjectEndpoint()
BasicInvocationHandler
's
ObjectEndpoint
.ObjectEndpoint
public final MethodConstraints getClientConstraints()
BasicInvocationHandler
's client
constraints.public final MethodConstraints getServerConstraints()
BasicInvocationHandler
's server
constraints.public int hashCode()
public boolean equals(Object obj)
BasicInvocationHandler
for equality.
BasicInvocationHandler
implements this method
to return true
if and only if
ObjectEndpoint
in the specified object has the
same class and is equal to the object endpoint in this object, and
A subclass should override this method if adds instance state that affects equality.
public boolean checkTrustEquivalence(Object obj)
true
if the specified object (which is not
yet known to be trusted) is equivalent in trust, content, and
function to this known trusted object, and false
otherwise.
BasicInvocationHandler
implements this method
to return true
if and only if
ObjectEndpoint
is an instance of
TrustEquivalence
and invoking its
checkTrustEquivalence
method with the specified
object's ObjectEndpoint
returns true
,
and
A subclass should override this method to perform any additional checks that are necessary.
checkTrustEquivalence
in interface TrustEquivalence
obj
- object to check that is not yet known to be trustedtrue
if the specified object (that is not yet
known to be trusted) is equivalent in trust, content, and function to
this known trusted object, and returns false
otherwiseCopyright 2007-2013, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.