Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## net.jini.jeri
Class BasicInvocationHandler

    java.lang.Object
      net.jini.jeri.BasicInvocationHandler

All Implemented Interfaces:
  InvocationHandler, Serializable, TrustEquivalence

public class BasicInvocationHandler
extends Object
implements InvocationHandler, TrustEquivalence, Serializable

A basic implementation of the `InvocationHandler` interface. This invocation handler implements 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.

Since:
  2.0
See Also:
  `BasicInvocationDispatcher`, Serialized Form
Implementation Specifics:

  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 Summary
`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.

Method Summary
`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.

Methods inherited from class java.lang.Object
`clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

Constructor Detail

### BasicInvocationHandler

    public BasicInvocationHandler(ObjectEndpoint oe,
                                  MethodConstraints serverConstraints)

  Creates a new `BasicInvocationHandler` with the specified `ObjectEndpoint` and server constraints.

  The client constraints of the created `BasicInvocationHandler` will be `null`.

Parameters:
  `oe` - the `ObjectEndpoint` for this invocation handler
  `serverConstraints` - the server constraints, or `null`
Throws:
  `NullPointerException` - if `oe` is `null`

### BasicInvocationHandler

    public 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`.

  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.

Parameters:
  `other` - the `BasicInvocationHandler` to obtain the `ObjectEndpoint` and server constraints from
  `clientConstraints` - the client constraints, or `null`
Throws:
  `NullPointerException` - if `other` is `null`

Method Detail

### invoke

    public Object invoke(Object proxy,
                         Method method,
                         Object[] args)
                  throws Throwable

  Processes a method invocation made on the encapsulating proxy instance, `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's `next` method is invoked to obtain an `OutboundRequest` for the current attempt. If `next` returns normally, the request's `getUnfulfilledConstraints` method is invoked, and if the returned requirements or preferences include `Integrity.YES`, object integrity is enforced for the current remote call attempt. If the returned requirements include any constraint other than an `Integrity` constraint, an `UnsupportedConstraintException` is generated and, as described below, wrapped and handled like any other `Exception` 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 the `OutboundRequest` 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, and `0x00` 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, passing `proxy`, `method`, the `OutboundRequest`, and the client context, to create the marshal output stream for marshalling the remote call.
  > - The `marshalMethod` method of this invocation handler is invoked with `proxy`, `method`, the marshal output stream, and the client context.
  > - The `marshalArguments` method of this 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 `executeCall` method is invoked with the `OutboundRequest`. If `executeCall` returns a `RemoteException`, then this method throws that exception (and thus the remote call attempt iteration terminates). If `executeCall` returns `null`, 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 `ProtocolException` is generated and, as described below, wrapped and handled like any other `Exception` thrown from a remote call attempt.
  > - If the byte is `0x01`, indicating a normal return, the `createMarshalInputStream` method is invoked, passing `proxy`, `method`, the `OutboundRequest`, a `boolean` 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 `unmarshalReturn` method of this invocation handler is invoked with `proxy`, `method`, the marshal input stream, and the client context. This method returns the value returned by `unmarshalReturn` (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 the `createMarshalInputStream` method as described for the previous case, and the `unmarshalThrow` method of this invocation handler is invoked with `proxy`, `method`, the marshal input stream, and the client context. This method throws the exception returned by `unmarshalThrow` (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 other `Exception` thrown from a remote call attempt.

  > If an `IOException` is thrown during the attempt to communicate the remote call, then it is wrapped in a `RemoteException` as follows:

  > - If `marshalMethod` was not invoked for this attempt, or if an invocation of `getDeliveryStatus` on the `OutboundRequest` returns `false`, or if a marshalling protocol version mismatch was detected, then
  >   - if the `IOException` is a `java.net.UnknownHostException`, it is wrapped in a `java.rmi.UnknownHostException`;
  >   - if it is a `java.net.ConnectException`, it is wrapped in a `java.rmi.ConnectException`;
  >   - if it is any other `IOException`, it is wrapped in a `ConnectIOException`.
  > - Otherwise, if `executeCall` was not invoked for this attempt, the `IOException` is wrapped in a `MarshalException`, and if `executeCall` was invoked, it is wrapped in an `UnmarshalException`.

  > If a `ClassNotFoundException` is thrown during the unmarshalling, then it is wrapped in an `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 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.

  Specified by:
    `invoke` in interface `InvocationHandler`
  Throws:
    `Throwable`
  See Also:
    `UndeclaredThrowableException`

### setClientConstraints

    protected InvocationHandler setClientConstraints(MethodConstraints constraints)

  Returns a copy of this invocation handler with the specified constraints as its new client 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.

  Parameters:
    `constraints` - the new client constraints, or `null`
  Returns:
    a copy of this invocation handler with the specified constraints as its client constraints

### createMarshalOutputStream

    protected ObjectOutputStream createMarshalOutputStream(Object proxy,
                                                           Method method,
                                                           OutboundRequest request,
                                                           Collection context)
                                                    throws IOException

  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`.

  `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.

  Parameters:
    `proxy` - the proxy instance
    `method` - the remote method invoked
    `request` - the outbound request
    `context` - the client context
  Returns:
    a new `ObjectOutputStream` instance for marshalling a call request
  Throws:
    `IOException` - if an I/O exception occurs
    `NullPointerException` - if any argument is `null`

### createMarshalInputStream

    protected ObjectInputStream createMarshalInputStream(Object proxy,
                                                         Method method,
                                                         OutboundRequest request,
                                                         boolean integrity,
                                                         Collection context)
                                                  throws IOException

  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`.

  `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.

  Parameters:
    `proxy` - the proxy instance
    `method` - the remote method invoked
    `request` - the outbound request
    `integrity` - whether or not to verify codebase integrity
    `context` - the client context
  Returns:
    a new `ObjectInputStream` instance for unmarshalling a call response
  Throws:
    `IOException` - if an I/O exception occurs
    `NullPointerException` - if any argument is `null`

### marshalMethod

    protected void marshalMethod(Object proxy,
                                 Method method,
                                 ObjectOutputStream out,
                                 Collection context)
                          throws IOException

  Marshals a representation of the given `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 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.

  Parameters:
    `proxy` - the proxy instance that the method was invoked on
    `method` - 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 call
    `context` - the client context
  Throws:
    `IOException` - if an I/O exception occurs
    `NullPointerException` - if any argument is `null`

### marshalArguments

    protected void marshalArguments(Object proxy,
                                    Method method,
                                    Object[] args,
                                    ObjectOutputStream out,
                                    Collection context)
                             throws IOException

  Marshals the arguments for the specified remote method to the outgoing request stream, `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.

  Parameters:
    `proxy` - the proxy instance that the method was invoked on
    `method` - 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 call
    `context` - the client context
  Throws:
    `IOException` - if an I/O exception occurs
    `NullPointerException` - if any argument is `null`

### unmarshalReturn

    protected Object unmarshalReturn(Object proxy,
                                     Method method,
                                     ObjectInputStream in,
                                     Collection context)
                              throws IOException,
                                     ClassNotFoundException

  Unmarshals the return value for the specified remote method from the incoming response stream, `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.

  Parameters:
    `proxy` - the proxy instance that the method was invoked on
    `method` - 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 call
    `context` - the client context
  Returns:
    the unmarshalled return value of the method invocation on the proxy instance. If the declared return value of the interface method is a primitive type, then the value returned by `invoke` will be an instance of the corresponding primitive wrapper class; otherwise, it will be a type assignable to the declared return type.
  Throws:
    `IOException` - if an I/O exception occurs
    `ClassNotFoundException` - if a class could not be found during unmarshalling
    `NullPointerException` - if any argument is `null`

### unmarshalThrow

    protected Throwable unmarshalThrow(Object proxy,
                                       Method method,
                                       ObjectInputStream in,
                                       Collection context)
                                throws IOException,
                                       ClassNotFoundException

  Unmarshals the throwable for the specified remote method from the incoming response stream, `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.

  Parameters:
    `proxy` - the proxy instance that the method was invoked on
    `method` - 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 context
    `in` - the incoming result stream for the remote call
  Returns:
    the unmarshalled exception to throw from the method invocation on the proxy instance. The exception's type must be assignable either to any of the exception types declared in the `throws` clause of the interface method or to the unchecked exception types `java.lang.RuntimeException` or `java.lang.Error`.
  Throws:
    `IOException` - if an I/O exception occurs
    `ClassNotFoundException` - if a class could not be found during unmarshalling
    `NullPointerException` - if any argument is `null`

### getObjectEndpoint

    public final ObjectEndpoint getObjectEndpoint()

  Returns this `BasicInvocationHandler`'s `ObjectEndpoint`.

  Returns:
    the `ObjectEndpoint`

### getClientConstraints

    public final MethodConstraints getClientConstraints()

  Returns this `BasicInvocationHandler`'s client constraints.

  Returns:
    the client constraints

### getServerConstraints

    public final MethodConstraints getServerConstraints()

  Returns this `BasicInvocationHandler`'s server constraints.

  Returns:
    the server constraints

### hashCode

    public int hashCode()

  Returns the hash code value for this invocation handler.

  Returns:
    the hash code value for this invocation handler

### equals

    public boolean equals(Object obj)

  Compares the specified object with this `BasicInvocationHandler` for equality.

  `BasicInvocationHandler` implements this method to return `true` if and only if

  - the specified object has the same class as this object,
  - the `ObjectEndpoint` in the specified object has the same class and is equal to the object endpoint in this object, and
  - the client constraints and server constraints in the specified object are equal to the ones in this object.

  A subclass should override this method if adds instance state that affects equality.

  Parameters:
    `obj` - the object to compare with
  Returns:
    `true` if `obj` is equivalent to this object; `false` otherwise

### checkTrustEquivalence

    public 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.

  `BasicInvocationHandler` implements this method to return `true` if and only if

  - the specified object has the same class as this object,
  - this object's `ObjectEndpoint` is an instance of `TrustEquivalence` and invoking its `checkTrustEquivalence` method with the specified object's `ObjectEndpoint` returns `true`, and
  - the client constraints and server constraints in the specified object are equal to the ones in this object.

  A subclass should override this method to perform any additional checks that are necessary.

  Specified by:
    `checkTrustEquivalence` in interface `TrustEquivalence`
  Parameters:
    `obj` - object to check that is not yet known to be trusted
  Returns:
    `true` 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` otherwise

### toString

    public String toString()

  Returns a string representation of this `BasicInvocationHandler`.

  Returns:
    a string representation of this `BasicInvocationHandler`

Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

Copyright © 2004 Sun Microsystems, Inc. All rights reserved