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 BasicJeriExporter

    java.lang.Object
      net.jini.jeri.BasicJeriExporter

All Implemented Interfaces:
  Exporter

public final class BasicJeriExporter
extends Object
implements Exporter

An `Exporter` implementation for exporting a remote object to use Jini(TM) extensible remote invocation (Jini ERI). Typically, instances of this class should be obtained from a `Configuration` rather than being explicitly constructed. Each instance of `BasicJeriExporter` can export only a single remote object.

The following properties (defined during construction) govern invocation behavior and other characteristics of the exported remote object and its proxy:

- `ServerEndpoint`: the `ServerEndpoint` over which calls are accepted.

- `InvocationLayerFactory`: a factory used to obtain the remote object's proxy and invocation dispatcher.

- enableDGC flag: if `true`, distributed garbage collection (DGC) is enabled for the exported remote object, and the `BasicObjectEndpoint` produced by this exporter participates in DGC and thus constitutes a strong remote reference to the remote object; if `false`, DGC is not enabled for the remote object, and the `BasicObjectEndpoint` does not participate in DGC and thus is a weak remote reference, so it does not prevent the remote object from being garbage collected.

- keepAlive flag: if `true`, the virtual machine is kept alive (with a non-daemon thread) while the remote object remains exported via this exporter.

- `Uuid`: the object identifier to use for the remote object; if `null`, a unique object identifier is chosen for the remote object using `UuidFactory.generate`.

If DGC is not enabled for a remote object, then the implementation always only weakly references the remote object. If DGC is enabled for a remote object, then the implementation weakly references the remote object when its referenced set is empty and strongly references the remote object when its referenced set is not empty (see below). If the implementation weakly references the remote object and the weak reference is cleared, the remote object becomes effectively unexported.

Enabling DGC is not advisable in some circumstances. DGC should not be enabled for a remote object exported with a well known object identifier. Enabling DGC with a secure remote object is generally discouraged, because DGC communication is always made in a client-side context in which there are no client constraints and no client subject, so it can leave the remote object open to denial of service attacks.

Multiple remote objects can be exported on the same server endpoint, and the same remote object can be exported multiple times on different server endpoints with the only restriction being that a given pair of object identifier and listen endpoint (derived from the server endpoint) can only have one active export at any given time.

Two instances of this class are equal only if they are references to the same (`==`) object.

The server endpoint is not transmitted in the remote reference; only the derived client endpoint is transmitted.

Remote objects exported with instances of this class can call `ServerContext.getServerContextElement`, passing the class `ClientSubject` to obtain the authenticated identity of the client (if any) for an incoming remote call, or passing the class `ClientHost` to obtain the address of the client host.

For remote objects exported with instances of this class, there is no automatic replacement of the proxy for the remote object during marshalling; either the proxy must be passed explicitly, or the remote object implementation class must be serializable and have a `writeReplace` method that returns its proxy.

#### Distributed Garbage Collection

The `BasicJeriExporter` class acts as the server-side DGC implementation for all remote objects exported with DGC enabled using its instances.

An entity known as the DGC client tracks the existence and reachability of live remote references (`BasicObjectEndpoint` instances that participate in DGC) for a `BasicObjectEndpoint` class in some (potentially) remote virtual machine. A DGC client is identified by a universally unique identifier (a `Uuid`). A DGC client sends dirty calls and clean calls to the `Endpoint` of a live remote reference to inform the server-side DGC implementation when the number of live remote references to a given remote object it is tracking increases from zero to greater than zero and decreases from greater than zero to zero, respectively. A DGC client also sends dirty calls to the `Endpoint` of live remote references it is tracking to renew its lease. The client-side behavior of dirty and clean calls is specified by `BasicObjectEndpoint`.

On the server side, for every remote object exported with DGC enabled, the implementation maintains a referenced set, which contains the `Uuid`s of the DGC clients that are known to have live remote references to the remote object. The contents of the referenced set are modified as a result of dirty calls, clean calls, and expiration of leases (see below). While the referenced set is not empty, the implementation strongly references the remote object, so that it will not be garbage collected. While the referenced set is empty, the implementation only weakly references the remote object, so that it may be garbage collected (if it is not otherwise strongly reachable locally). If a remote object is garbage collected, it becomes effectively unexported. If a remote object that is an instance of `Unreferenced` is exported with DGC enabled, then whenever the size of its referenced set transitions from greater than zero to zero, its `unreferenced` method will be invoked (before the strong reference is dropped). Note that a referenced set spans multiple exports of the same (identical) remote object with `BasicJeriExporter`.

Every `RequestDispatcher` passed by `BasicJeriExporter` to a `ListenEndpoint` as part of exporting has an implicitly and permanently exported remote object, which represents the server-side DGC implementation. This remote object is effectively exported with an object identifier of `d32cd1bc-273c-11b2-8841-080020c9e4a1` and an `InvocationDispatcher` that behaves like a `BasicInvocationDispatcher` with no server constraints and with support for at least the following remote methods:

         long dirty(Uuid clientID, long sequenceNum, Uuid[] ids)
             throws RemoteException;

         void clean(Uuid clientID, long sequenceNum, Uuid[] ids, boolean strong)
             throws RemoteException;

`clientID` identifies the DGC client that is making the dirty or clean call, and `sequenceNum` identifies the sequence number of the dirty or clean call with respect to other dirty and clean calls from the same DGC client. The sequence numbers identify the correct order of semantic interpretation of dirty and clean calls from the same DGC client, regardless of the order in which they arrive.

A dirty call is processed as follows:

- It establishes or renews the DGC lease for the identified DGC client. The duration of the granted lease, which is chosen by the implementation, is conveyed as the value returned by the dirty call, in milliseconds starting from the some time during the processing of the dirty call. While the lease for a DGC client is valid (not expired), the DGC client is preserved in referenced sets of exported remote objects.

- It adds the DGC client's `Uuid` to the referenced sets of the exported remote objects identified by `ids`, if any, so that they are prevented from being garbage collected. For each `Uuid` in `ids`:

  > The identified remote object is the remote object exported with that `Uuid` on the `ListenEndpoint` (and thus `RequestDispatcher`) that the dirty call was received on. If no such exported remote object exists (for example, if it has been garbage collected), then that `Uuid` in `ids` is ignored. If the sequence number is less than the last recorded sequence number of a dirty or clean call for the identified remote object from the same DGC client, then the remote object's referenced set is not modified. Otherwise, the DGC client's `Uuid` is added to the remote object's referenced set (if not already present). If this addition causes the referenced set to transition from empty to non-empty, then the implementation starts strongly referencing the remote object.

A clean call is processed as follows:

- It removes the DGC client's `Uuid` from the referenced sets of the exported remote objects identified by `ids`, so that they are not prevented from being garbage collected by the given DGC client. For each `Uuid` in `ids`:

  > The identified remote object is the remote object exported with that `Uuid` on the `ListenEndpoint` (and thus `RequestDispatcher`) that the dirty call was received on. If no such exported remote object exists (for example, if it has been garbage collected), then that `Uuid` in `ids` is ignored. If the sequence number is less then the last recorded sequence number of a dirty or clean call for the identified remote object from the same DGC client, then the remote object's referenced set is not modified. Otherwise, the DGC client's `Uuid` is removed from the remote object's referenced set (if it is present). If this removal causes the referenced set to transition from non-empty to empty, then the implementation starts only weakly referencing the remote object (and before doing so, if the remote object is an instance of `Unreferenced`, its `unreferenced` method is invoked). If `strong` is `true`, then a record is kept of the specified sequence number from the DGC client for some reasonable period of time, in the event of a dirty call that might arrive later with a lower sequence number.

If the implementation detects that the most recently granted DGC lease for a given DGC client has expired, then it assumes that the DGC client has abnormally terminated, and the DGC client's `Uuid` is removed from the referenced sets of all exported remote objects. If this removal causes a referenced set to transition from non-empty to empty, then the implementation starts only weakly referencing the corresponding remote object (and before doing so, if the remote object is an instance of `Unreferenced`, its `unreferenced` method is invoked).

Unexporting a remote object with a `BasicJeriExporter` causes the removal of DGC client `Uuid`s from the remote object's referenced set that were only present because of dirty calls that were received as a result of exporting it with that `BasicJeriExporter`. If the remote object remains exported with DGC enabled by another `BasicJeriExporter` and this removal causes the referenced set to transition from non-empty to empty, then the implementation starts only weakly referencing the remote object (and before doing so, if the remote object is an instance of `Unreferenced`, its `unreferenced` method is invoked).

When the implementation invokes a remote object's `unreferenced` method, it does so with the security context and context class loader in effect when the remote object was exported. If the remote object is currently exported more than once, then the security context and context class loader in effect for any one of those exports are used.

Since:
  2.0
Implementation Specifics:

  This implementation uses the `Logger` named `net.jini.jeri.BasicJeriExporter` to log information at the following levels:

  Level | Description
  --- | ---
  `FAILED` | incoming request for unrecognized object identifier (no such object)
  `FAILED` | I/O exception dispatching incoming request
  `FINE` | successful export of object
  `FINE` | attempted unexport of object
  `FINE` | garbage collection of exported object
  `FINEST` | detailed implementation activity

Constructor Summary
`BasicJeriExporter(ServerEndpoint se, InvocationLayerFactory ilf)` Creates a new `BasicJeriExporter` with the given server endpoint and invocation layer factory.
`BasicJeriExporter(ServerEndpoint se, InvocationLayerFactory ilf, boolean enableDGC, boolean keepAlive)` Creates a new `BasicJeriExporter` with the given server endpoint, invocation layer factory, `enableDGC` flag, and `keepAlive` flag.
`BasicJeriExporter(ServerEndpoint se, InvocationLayerFactory ilf, boolean enableDGC, boolean keepAlive, Uuid id)` Creates a new `BasicJeriExporter` with the given server endpoint, invocation layer factory, `enableDGC` flag, `keepAlive` flag, and object identifier.

Method Summary
`Remote` | `export(Remote impl)` Exports the specified remote object and returns a proxy for the remote object.
`boolean` | `getEnableDGC()` Returns `true` if DGC is enabled on the server endpoint to the object corresponding to this exporter; otherwise returns `false`.
`InvocationLayerFactory` | `getInvocationLayerFactory()` Returns the `InvocationLayerFactory` for this exporter.
`boolean` | `getKeepAlive()` Returns `true` if the virtual machine is kept alive while the object corresponding to this exporter is exported; otherwise returns `false`.
`Uuid` | `getObjectIdentifier()` Returns the object identifier for this exporter.
`ServerEndpoint` | `getServerEndpoint()` Returns the server endpoint for this exporter.
`String` | `toString()` Returns the string representation for this exporter.
`boolean` | `unexport(boolean force)` Unexports the remote object exported via the exporter's `export` method such that incoming remote calls to the object identifier in this exporter are no longer accepted through the server endpoint in this exporter.

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

Constructor Detail

### BasicJeriExporter

    public BasicJeriExporter(ServerEndpoint se,
                             InvocationLayerFactory ilf)

  Creates a new `BasicJeriExporter` with the given server endpoint and invocation layer factory. The other properties of the exporter default as follows: the `enableDGC` flag is `false`, the `keepAlive` flag is `true`, and the object identifier is chosen by invoking `UuidFactory.generate`.

Parameters:
  `se` - the server endpoint over which calls may be accepted
  `ilf` - the factory for creating the remote object's proxy and invocation dispatcher
Throws:
  `NullPointerException` - if `se` or `ilf` is `null`

### BasicJeriExporter

    public BasicJeriExporter(ServerEndpoint se,
                             InvocationLayerFactory ilf,
                             boolean enableDGC,
                             boolean keepAlive)

  Creates a new `BasicJeriExporter` with the given server endpoint, invocation layer factory, `enableDGC` flag, and `keepAlive` flag. The object identifier is chosen by invoking `UuidFactory.generate`.

Parameters:
  `se` - the server endpoint over which calls may be accepted
  `ilf` - the factory for creating the remote object's proxy and invocation dispatcher
  `enableDGC` - if `true`, DGC is enabled to the object on this server endpoint
  `keepAlive` - if `true`, the VM is kept alive while the object (exported via this exporter) remains exported
Throws:
  `NullPointerException` - if `se` or `ilf` is `null`

### BasicJeriExporter

    public BasicJeriExporter(ServerEndpoint se,
                             InvocationLayerFactory ilf,
                             boolean enableDGC,
                             boolean keepAlive,
                             Uuid id)

  Creates a new `BasicJeriExporter` with the given server endpoint, invocation layer factory, `enableDGC` flag, `keepAlive` flag, and object identifier. If `id` is `null`, the object identifier is chosen by invoking `UuidFactory.generate`.

Parameters:
  `se` - the server endpoint over which calls may be accepted
  `ilf` - the factory for creating the remote object's proxy and invocation dispatcher
  `enableDGC` - if `true`, DGC is enabled to the object on this server endpoint
  `keepAlive` - if `true`, the VM is kept alive while the object (exported via this exporter) remains exported
  `id` - an object identifier or `null`
Throws:
  `NullPointerException` - if `se` or `ilf` is `null`

Method Detail

### getServerEndpoint

    public ServerEndpoint getServerEndpoint()

  Returns the server endpoint for this exporter.

  Returns:
    the server endpoint

### getInvocationLayerFactory

    public InvocationLayerFactory getInvocationLayerFactory()

  Returns the `InvocationLayerFactory` for this exporter.

  Returns:
    the factory

### getEnableDGC

    public boolean getEnableDGC()

  Returns `true` if DGC is enabled on the server endpoint to the object corresponding to this exporter; otherwise returns `false`.

  Returns:
    `true` if DGC is enabled; `false` otherwise

### getKeepAlive

    public boolean getKeepAlive()

  Returns `true` if the virtual machine is kept alive while the object corresponding to this exporter is exported; otherwise returns `false`.

  Returns:
    `true` if VM is kept alive while object is exported; `false` otherwise

### getObjectIdentifier

    public Uuid getObjectIdentifier()

  Returns the object identifier for this exporter.

  Returns:
    the object identifier

### export

    public Remote export(Remote impl)
                  throws ExportException

  Exports the specified remote object and returns a proxy for the remote object. This method cannot be called more than once to export a remote object or an `IllegalStateException` will be thrown.

  A `BasicObjectEndpoint` instance is created with the object identifier of this exporter, the `Endpoint` obtained from listening on the server endpoint (see below), and the `enableDGC` flag of this exporter.

  The client `Endpoint` for the `BasicObjectEndpoint` is obtained by invoking `enumerateListenEndpoints` on the server endpoint with a `ServerEndpoint.ListenContext` whose `addListenEndpoint` method is implemented as follows:

  - Invokes `checkPermissions` on the supplied listen endpoint.
  - If the supplied listen endpoint has the same class and is equal to another listen endpoint that has already been listened on, returns the `ServerEndpoint.ListenCookie` corresponding to the previous `listen` operation. Otherwise, it creates a `RequestDispatcher` to handle inbound requests dispatched by the listen endpoint, invokes `listen` on the listen endpoint (passing the request dispatcher) within an action passed to the `Security.doPrivileged` method, and returns the `ServerEndpoint.ListenCookie` obtained by invoking `getCookie` on the `ServerEndpoint.ListenHandle` returned from the `listen` invocation.

  A `RequestDispatcher` for a listen endpoint handles a dispatched inbound request (when its `dispatch` method is invoked) as follows. The request dispatcher reads the object identifer of the target object being invoked by invoking `UuidFactory.read` on the request input stream of the inbound request. If no exported object corresponds to the object identifier read, it closes the request input stream, writes `0x00` to the response output stream, and closes the response output stream. Otherwise, it writes `0x01` to the response output stream, and invokes the `dispatch` method on the invocation dispatcher passing the target object, the inbound request, and the server context collection (see below).

  A proxy and an invocation dispatcher are created by calling the `createInstances` method of this exporter's invocation layer factory, passing the remote object, the `BasicObjectEndpoint`, and the server endpoint (as the `ServerCapabilities`). The proxy is returned by this method. The invocation dispatcher is called for each incoming remote call to this exporter's object identifier received from this exporter's server endpoint, passing the remote object and the `InboundRequest` received from the transport layer.

  Each call to the invocation dispatcher's `dispatch` method is invoked with the following thread context:

  - `dispatch` is invoked in a `PrivilegedAction` wrapped by a `SecurityContext` obtained when this method was invoked, with the `AccessControlContext` of that `SecurityContext` in effect.
  - The context class loader is the context class loader in effect when this method was invoked.
  - Each call to the dispatcher is made using `ServerContext.doWithServerContext` with a server context collection that is an unmodifiable view of the context collection populated by invoking the `populateContext` method on the inbound request passing a modifiable collection. The invocation dispatcher's `dispatch` method is invoked with the `impl`, the inbound request, and that modifiable server context collection.

  There is no replacement of the proxy for the implementation object during marshalling; either the proxy must be passed explicitly in a remote call, or the implementation class must be serializable and have a `writeReplace` method that returns the proxy.

  Specified by:
    `export` in interface `Exporter`
  Parameters:
    `impl` - a remote object to export
  Returns:
    a proxy for the remote object
  Throws:
    `ExportException` - if an object is already exported with the same object identifier and server endpoint, or the invocation layer factory cannot create a proxy or invocation dispatcher, or some other problem occurs while exporting the object
    `NullPointerException` - if `impl` is `null`
    `IllegalStateException` - if an object has already been exported with this `Exporter` instance
    `SecurityException` - if invoking the `checkPermissions` method on any of the listen endpoints throws a `SecurityException`

### unexport

    public boolean unexport(boolean force)

  Unexports the remote object exported via the exporter's `export` method such that incoming remote calls to the object identifier in this exporter are no longer accepted through the server endpoint in this exporter.

  If `force` is `true`, the object is forcibly unexported even if there are pending or in-progress remote calls to the object identifier through the server endpoint. If `force` is `false`, the object is only unexported if there are no pending or in-progress remote calls to the object identifier through the server endpoint.

  The return value is `true` if the object is (or was previously) unexported, and `false` if the object is still exported.

  Specified by:
    `unexport` in interface `Exporter`
  Parameters:
    `force` - if `true`, the remote object will be unexported even if there are remote calls pending or in progress; if `false`, the remote object may only be unexported if there are no known remote calls pending or in progress
  Returns:
    `true` if the remote object is unexported when this method returns and `false` otherwise
  Throws:
    `IllegalStateException` - if an object has not been exported with this `Exporter` instance

### toString

    public String toString()

  Returns the string representation for this exporter.

  Returns:
    the string representation for this exporter

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