public class BasicInvocationDispatcher extends Object implements InvocationDispatcher
InvocationDispatcher interface,
providing preinvocation access control for
remote objects exported using BasicJeriExporter.
This invocation dispatcher handles incoming remote method invocations
initiated by proxies using BasicInvocationHandler, and expects
that a dispatched request, encapsulated in the InboundRequest
object passed to the dispatch method, was sent using
the protocol implemented by BasicInvocationHandler.
A basic permission-based preinvocation access control mechanism is
provided. A permission class can be specified when an invocation
dispatcher is constructed; instances of that class are constructed using
either a Method instance or a String representing
the remote method being invoked. The class can have a constructor with a
Method parameter to permit an arbitrary mapping to the
actual permission target name and actions; otherwise, the class must
have a constructor taking the fully qualified name of the remote method
as a String. For each incoming call on a remote object, the
client subject must be granted the associated permission for that remote
method. (Access control for an individual remote method can effectively
be disabled by granting the associated permission to all protection
domains.) A simple subclass of AccessPermission is typically
used as the permission class.
Other access control mechanisms can be implemented by subclassing this class and overriding the various protected methods.
This class is designed to support dispatching remote calls to the
ProxyTrust.getProxyVerifier method
to the local ServerProxyTrust.getProxyVerifier method of a remote object, to allow a
remote object to be exported in such a way that its proxy can be
directly trusted by clients as well as in such a way that its proxy can
be trusted by clients using ProxyTrustVerifier.
BasicInvocationHandlerorg.apache.river.jeri.server.suppressStackTrace
true, removes server-side stack traces before
marshalling an exception thrown as a result of a remote call. The
default value is false.
This implementation uses the Logger named
net.jini.jeri.BasicInvocationDispatcher to log
information at the following levels:
| Level | Description |
|---|---|
FAILED | exception that caused a request to be aborted |
FAILED | exceptional result of a remote call |
FINE | incoming remote call |
FINE | successful return of remote call |
FINEST | more detailed information on the above (for example, actual argument and return values) |
| Constructor and Description |
|---|
BasicInvocationDispatcher(Collection methods,
ServerCapabilities serverCapabilities,
MethodConstraints serverConstraints,
Class permissionClass,
ClassLoader loader)
Creates an invocation dispatcher to receive incoming remote calls
for the specified methods, for a server and transport with the
specified capabilities, enforcing the specified constraints,
performing preinvocation access control using the specified
permission class (if any).
|
| Modifier and Type | Method and Description |
|---|---|
protected void |
checkAccess(Remote impl,
Method method,
InvocationConstraints constraints,
Collection context)
Checks that the client has permission to invoke the specified method on
the specified remote object.
|
static void |
checkClientPermission(Permission permission)
Checks that the client subject for the current remote call has the
specified permission.
|
static void |
checkPermissionClass(Class permissionClass)
Checks that the specified class is a valid permission class for use in
preinvocation access control.
|
protected ObjectInputStream |
createMarshalInputStream(Object impl,
InboundRequest request,
boolean integrity,
Collection context)
Returns a new marshal input stream to use to read objects from the
request input stream obtained by invoking the
getRequestInputStream method
on the given request. |
protected ObjectOutputStream |
createMarshalOutputStream(Object impl,
Method method,
InboundRequest request,
Collection context)
Returns a new marshal output stream to use to write objects to the
response output stream obtained by invoking the
getResponseOutputStream
method on the given request. |
void |
dispatch(Remote impl,
InboundRequest request,
Collection context)
Dispatches the specified inbound request to the specified remote object.
|
protected ClassLoader |
getClassLoader()
Returns the class loader specified during construction.
|
protected Object |
invoke(Remote impl,
Method method,
Object[] args,
Collection context)
Invokes the specified
method on the specified remote
object impl, with the specified arguments. |
protected void |
marshalReturn(Remote impl,
Method method,
Object returnValue,
ObjectOutputStream out,
Collection context)
Marshals the specified return value for the specified remote method
to the marshal output stream,
out. |
protected void |
marshalThrow(Remote impl,
Method method,
Throwable throwable,
ObjectOutputStream out,
Collection context)
Marshals the
throwable for the specified remote method
to the marshal output stream, out. |
protected Object[] |
unmarshalArguments(Remote impl,
Method method,
ObjectInputStream in,
Collection context)
Unmarshals the arguments for the specified remote
method
from the specified marshal input stream, in, and returns an
Object array containing the arguments read. |
protected Method |
unmarshalMethod(Remote impl,
ObjectInputStream in,
Collection context)
Unmarshals a method representation from the marshal input stream,
in, and returns the Method object
corresponding to that representation. |
public BasicInvocationDispatcher(Collection methods, ServerCapabilities serverCapabilities, MethodConstraints serverConstraints, Class permissionClass, ClassLoader loader) throws ExportException
createMarshalInputStream
method.
For each combination of constraints that might need to be
enforced (obtained by calling the possibleConstraints method on
the specified server constraints, or using an empty constraints
instance if the specified server constraints instance is
null), calling the checkConstraints method of the
specified capabilities object with those constraints must return
constraints containing at most an Integrity constraint as a
requirement, or an ExportException is thrown.
methods - a collection of Method instances for the
remote methodsserverCapabilities - the transport capabilities of the serverserverConstraints - the server constraints, or nullpermissionClass - the permission class, or nullloader - the class loader, or nullSecurityException - if the permission class is not
null and is in a named package and a
security manager exists and invoking its
checkPackageAccess method with the package
name of the permission class throws a
SecurityExceptionIllegalArgumentException - if the permission class
is abstract, is not public, is not a subclass
of Permission, or does not have a public
constructor that has either one String
parameter or one Method parameter and has no
declared exceptions, or if any element of
methods is not a Method instanceNullPointerException - if methods or
serverCapabilities is null, or if
methods contains a null elementExportException - if any of the possible server constraints
cannot be satisfied according to the specified server
capabilitiesprotected final ClassLoader getClassLoader()
public static void checkPermissionClass(Class permissionClass)
permissionClass - the permission class, or nullIllegalArgumentException - if the permission class is abstract,
is not a subclass of Permission, or does not have a public
constructor that has either one String parameter or one
Method parameter and has no declared exceptionspublic void dispatch(Remote impl, InboundRequest request, Collection context)
BasicJeriExporter, this
method is called in a context that has the security context and
context class loader specified by
BasicJeriExporter.export.
BasicInvocationDispatcher implements this method to
execute the following actions in order:
0x00, two byte values of 0x00 (indicating
a marshal stream protocol version mismatch) are written to the
response output stream of the inbound request, the output stream is
closed, and this method returns.
0x00, a second byte
specifying object integrity is read from the same stream. If any
exception is thrown when reading this byte, the inbound request is
aborted and this method returns. Object integrity will be enforced
if the value read is not 0x00, but will not be enforced
if the value is 0x00. An IntegrityEnforcement element is then added to
the server context, reflecting whether or not object integrity is
being enforced.
createMarshalInputStream
method of this invocation dispatcher is called, passing the remote
object, the inbound request, a boolean indicating if object
integrity is being enforced, and the server context, to create the
marshal input stream for unmarshalling the request.
unmarshalMethod of this
invocation dispatcher is called with the remote object, the marshal
input stream, and the server context to obtain the remote method.
checkConstraints
method of the inbound request is called with the constraints that
must be enforced for that remote method, obtained by passing the
remote method to the getConstraints method of this invocation dispatcher's server
constraints, and adding Integrity.YES as a
requirement if object integrity is being enforced. If the
unfulfilled requirements returned by checkConstraints
contains a constraint that is not an instance of Integrity
or if integrity is not being enforced and the returned requirements
contains the element Integrity.YES, an
UnsupportedConstraintException is sent back to the
caller as described further below. Otherwise, the checkAccess method of this invocation dispatcher is
called with the remote object, the remote method, the enforced
constraints, and the server context.
unmarshalArguments method of this invocation
dispatcher with the remote object, the remote method, the marshal
input stream, and the server context.
IOException,
ClassNotFoundException, or NoSuchMethodException), the
exception is first wrapped in an UnmarshalException and the
wrapped exception is sent back.
invoke method of this invocation dispatcher is then called with the
remote object, the remote method, the arguments returned by
unmarshalArguments, and the server context. If
invoke throws an exception, that exception is sent back
to the caller as described further below.
invoke returns normally, a byte value of
0x01 is written to the response output stream of the
inbound request. Then the createMarshalOutputStream method of this invocation dispatcher is
called, passing the remote object, the remote method, the inbound
request, and the server context, to create the marshal output stream
for marshalling the response. Then the marshalReturn method of this invocation dispatcher is called with
the remote object, the remote method, the value returned by
invoke, the marshal output stream, and the server
context. Then the marshal output stream is closed. Any exception
thrown during this marshalling is ignored.
0x02 is written to the response output stream of the
inbound request. Then a marshal output stream is created by calling
the createMarshalOutputStream method as described above
(but with a null remote method if one was not
successfully unmarshalled). Then the marshalThrow method of this invocation dispatcher is called with
the remote object, the remote method (or null if one
was not successfully unmarshalled), the exception, the marshal
output stream, and the server context. Then the marshal output
stream is closed. Any exception thrown during this marshalling is
ignored. If the exception being sent back is a
RemoteException, it is wrapped in a ServerException and the wrapped exception is passed to
marshalThrow. If the exception being sent back is an
Error, it is wrapped in a ServerError and the
wrapped exception is passed to marshalThrow. If the
exception being sent back occurred before or during the call to
unmarshalMethod, then the remote method passed to
marshalThrow is null.
dispatch in interface InvocationDispatcherimpl - a remote objectrequest - inbound request object for reading arguments and
writing the resultcontext - a modifiable server context collectionNullPointerException - if any argument is nullprotected ObjectInputStream createMarshalInputStream(Object impl, InboundRequest request, boolean integrity, Collection context) throws IOException
getRequestInputStream method
on the given request.
BasicInvocationDispatcher implements this method as
follows:
First, a class loader is selected to use as the
defaultLoader and the verifierLoader for
the marshal input stream instance. If the class loader specified at
construction is not null, the selected loader is that
loader. Otherwise, if a security manager exists, its checkPermission method is invoked
with the permission ; this invocation may
throw a RuntimePermission("getClassLoader")SecurityException. If the above security check
succeeds, the selected loader is the class loader of
impl's class.
This method returns a new MarshalInputStream instance
constructed with the input stream (obtained from the
request as specified above) for the input stream
in, the selected loader for defaultLoader
and verifierLoader, the boolean integrity
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.
A subclass can override this method to control how the marshal input stream is created or implemented.
impl - the remote objectrequest - the inbound requestintegrity - true if object integrity is being
enforced for the remote call, and false otherwisecontext - the server contextIOException - if an I/O exception occursNullPointerException - if any argument is nullprotected ObjectOutputStream createMarshalOutputStream(Object impl, Method method, InboundRequest request, Collection context) throws IOException
getResponseOutputStream
method on the given request.
This method will be called with a null
method argument if an IOException occurred
when reading method information from the incoming call stream.
BasicInvocationDispatcher implements this method to
return a new MarshalOutputStream instance constructed with
the output stream obtained from the request as
specified above and an unmodifiable view of the given
context collection.
A subclass can override this method to control how the marshal output stream is created or implemented.
impl - the remote objectmethod - the possibly-null Method
instance corresponding to the interface method invoked on
the remote objectrequest - the inbound requestcontext - the server contextIOException - if an I/O exception occursNullPointerException - if impl,
request, or context is
nullprotected void checkAccess(Remote impl, Method method, InvocationConstraints constraints, Collection context)
BasicInvocationDispatcher implements this method as
follows:
If a permission class was specified when this invocation
dispatcher was constructed, checkClientPermission is called with a permission constructed from
the permission class. If the permission class has a constructor with
a Method parameter, the permission is constructed by
passing the specified method to that constructor. Otherwise the
permission is constructed by passing the fully qualified name of the
method to the constructor with a String parameter,
where the argument is formed by concatenating the name of the
declaring class of the specified method and the name of the method,
separated by ".".
A subclass can override this method to implement other preinvocation access control mechanisms.
impl - the remote objectmethod - the remote methodconstraints - the enforced constraints for the specified
method, or nullcontext - the server contextSecurityException - if the current client subject does not
have permission to invoke the methodIllegalStateException - if the current thread is not executing an
incoming remote call for a remote objectNullPointerException - if impl,
method, or context is
nullpublic static void checkClientPermission(Permission permission)
ServerContext.getServerContextElement, passing the class ClientSubject, and then calling the getClientSubject method of the returned
element (if any). If a security manager is installed, a ProtectionDomain is constructed with an empty CodeSource
(null location and certificates), null
permissions, null class loader, and the principals from
the client subject (if any), and the implies method of
that protection domain is invoked with the specified permission. If
true is returned, this method returns normally, otherwise
a SecurityException is thrown. If no security
manager is installed, this method returns normally.
Note that the permission grant required to satisfy this check must be to the client's principals alone (or a subset thereof); it cannot be qualified by what code is being executed. At the point in a remote call where this method is intended to be used, the useful "call stack" only exists at the other end of the remote call (on the client side), and so cannot meaningfully enter into the access control decision.
permission - the requested permissionSecurityException - if the current client subject has not
been granted the specified permissionIllegalStateException - if the current thread is not executing
an incoming remote method for a remote objectNullPointerException - if permission is
nullprotected Method unmarshalMethod(Remote impl, ObjectInputStream in, Collection context) throws IOException, NoSuchMethodException, ClassNotFoundException
in, and returns the Method object
corresponding to that representation. For each remote call, the
dispatch method calls this method to unmarshal the
method representation.
BasicInvocationDispatcher implements this method to
call the readLong method on the marshal input stream to
read the method's representation encoded as a JRMP method hash
(defined in section 8.3 of the Java(TM) Remote Method Invocation
(Java RMI) specification) and return its
corresponding Method object chosen from the collection
of methods passed to the constructor of this invocation dispatcher.
If more than one method has the same hash, it is arbitrary as to
which one is returned.
A subclass can override this method to control how the remote method is unmarshalled.
impl - the remote objectin - the marshal input stream for the remote callcontext - the server context passed to the dispatch method for the remote call being processedMethod object corresponding to the method
representationIOException - if an I/O exception occursNoSuchMethodException - if the method representation does not
correspond to a valid methodClassNotFoundException - if a class could not be found during
unmarshallingNullPointerException - if any argument is nullprotected Object[] unmarshalArguments(Remote impl, Method method, ObjectInputStream in, Collection context) throws IOException, ClassNotFoundException
method
from the specified marshal input stream, in, and returns an
Object array containing the arguments read. For each
remote call, the dispatch method calls this method to
unmarshal arguments.
BasicInvocationDispatcher implements this method to
unmarshal each argument as follows:
If the corresponding declared parameter type is primitive, then
the primitive value is read from the stream using the
corresponding read method for that primitive type (for
example, if the type is int.class, then the primitive
int value is read to the stream using the
readInt method) and the value is wrapped in the
corresponding primitive wrapper class for that type (e.g.,
Integer for int, etc.). Otherwise, the
argument is read from the stream using the readObject
method and returned as is.
A subclass can override this method to unmarshal the arguments in an alternative context, perform post-processing on the arguments, unmarshal additional implicit data, or otherwise control how the arguments are unmarshalled. In general, the context used should mirror the context in which the arguments are manipulated in the implementation of the remote object.
impl - the remote objectmethod - the Method instance corresponding
to the interface method invoked on the remote objectin - the incoming request stream for the remote callcontext - the server context passed to the dispatch method for the remote call being processedObject array containing
the unmarshalled arguments. If an argument's corresponding
declared parameter type is primitive, then its value is
represented with an instance of the corresponding primitive
wrapper class; otherwise, the value for that argument is an
object of a class assignable to the declared parameter type.IOException - if an I/O exception occursClassNotFoundException - if a class could not be found during
unmarshallingNullPointerException - if any argument is nullprotected Object invoke(Remote impl, Method method, Object[] args, Collection context) throws Throwable
method on the specified remote
object impl, with the specified arguments.
If the invocation completes normally, the return value will be
returned by this method. If the invocation throws an exception,
this method will throw the same exception.
BasicInvocationDispatcher implements this method as
follows:
If the specified method is not set accessible or is not a
public method of a public class an
IllegalArgumentException is thrown.
If the specified method is ProxyTrust.getProxyVerifier and the remote object is an instance of
ServerProxyTrust, the getProxyVerifier method of the remote object is called and the result
is returned.
Otherwise, the specified method's invoke method is
called with the specified remote object and the specified arguments,
and the result is returned. If invoke throws an InvocationTargetException, that exception is caught and the target
exception inside it is thrown to the caller. Any other exception
thrown during any of this computation is thrown to the caller.
A subclass can override this method to invoke the method in an alternative context, perform pre- or post-processing, or otherwise control how the method is invoked.
impl - the remote objectmethod - the Method instance corresponding
to the interface method invoked on the remote objectargs - the method argumentscontext - the server context passed to the dispatch method for the remote call being processedimplNullPointerException - if any argument is nullThrowable - the exception thrown from the method invocation
on implprotected void marshalReturn(Remote impl, Method method, Object returnValue, ObjectOutputStream out, Collection context) throws IOException
out. After invoking
the method on the remote object impl, the
dispatch method calls this method to marshal the value
returned from the invocation on that remote object.
BasicInvocationDispatcher implements this method as
follows:
If the declared return type of the method is void, then no return
value is written to the stream. If the return type is a primitive
type, then 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 return value is
written to the stream using the writeObject method.
A subclass can override this method to marshal the return value in an alternative context, perform pre- or post-processing on the return value, marshal additional implicit data, or otherwise control how the return value is marshalled. In general, the context used should mirror the context in which the result is computed in the implementation of the remote object.
impl - the remote objectmethod - the Method instance corresponding
to the interface method invoked on the remote objectreturnValue - the return value to marshal to the streamout - the marshal output streamcontext - the server context passed to the dispatch method for the remote call being processedIOException - if an I/O exception occursNullPointerException - if impl,
method, out, or
context is nullprotected void marshalThrow(Remote impl, Method method, Throwable throwable, ObjectOutputStream out, Collection context) throws IOException
throwable for the specified remote method
to the marshal output stream, out. For each method
invocation on impl that throws an exception, this
method is called to marshal the throwable. This method is also
called if an exception occurs reading the method information from
the incoming call stream, as a result of calling unmarshalMethod; in this case, the
Method instance will be null.
BasicInvocationDispatcher implements this method to
marshal the throwable to the stream using the
writeObject method.
A subclass can override this method to marshal the throwable in an alternative context, perform pre- or post-processing on the throwable, marshal additional implicit data, or otherwise control how the throwable is marshalled. In general, the context used should mirror the context in which the exception is generated in the implementation of the remote object.
impl - the remote objectmethod - the possibly-null Method
instance corresponding to the interface method invoked on
the remote objectthrowable - a throwable to marshal to the streamout - the marshal output streamcontext - the server contextIOException - if an I/O exception occursNullPointerException - if impl,
throwable, out, or
context is nullCopyright 2007-2013, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.