net.jini.jeri
Class BasicJeriExporter

java.lang.Object
  extended by 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 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:

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. Some transport providers may not support making requests without a client subject, so even if DGC is enabled in the case where such a transport provider is used, DGC will be effectively disabled on the client side.

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

For every RequestDispatcher passed by BasicJeriExporter to a ListenEndpoint as part of exporting, whenever it has at least one remote object exported with DGC enabled, it also has an implicitly exported remote object that 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, with a createMarshalInputStream implementation that returns a MarshalInputStream that ignores codebase annotations, 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. The well-known object identifier for the server-side DGC implementation is reserved; attempting to export any other remote object with that object identifier always throws an ExportException.

A dirty call is processed as follows:

A clean call is processed as follows:

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 Uuids 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
Author:
Sun Microsystems, Inc.
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:

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:

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.

Overrides:
toString in class Object
Returns:
the string representation for this exporter


Copyright 2007, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.