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 {@link Configuration} rather than being explicitlyconstructed. 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
over which calls are accepted. {@link 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 {@link BasicObjectEndpoint} produced by this exporterparticipates 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.
{@link Uuid Uuid}: the object identifier to use for the remote object; if null
, a unique object identifier is chosen for the remote object using {@link UuidFactory#generate 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. 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 {@link ServerContext#getServerContextElement ServerContext.getServerContextElement}, passing the class {@link ClientSubject} to obtain the authenticated identity of the client (ifany) for an incoming remote call, or passing the class {@link 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.
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 {@link Endpoint} of a live remote reference to inform theserver-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 {@link 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 {@link Unreferenced} is exported with DGC enabled, then whenever the sizeof its referenced set transitions from greater than zero to zero, its {@link Unreferenced#unreferenced unreferenced} method will beinvoked (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 {@link BasicInvocationDispatcher} with no server constraints, with a{@link BasicInvocationDispatcher#createMarshalInputStream createMarshalInputStream} implementation that returns a {@link MarshalInputStream} that ignores codebase annotations, and withsupport for at least the following remote methods:
long dirty(Uuid clientID, long sequenceNum, Uuid[] ids) throws {@link 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 {@link ExportException}. A dirty call is processed as follows:
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 thatUuid
on theListenEndpoint
(and thusRequestDispatcher
) that the dirty call was received on. If no such exported remote object exists (for example, if it has been garbage collected), then thatUuid
inids
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'sUuid
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:
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 theListenEndpoint
(and thusRequestDispatcher
) that the dirty call was received on. If no such exported remote object exists (for example, if it has been garbage collected), then thatUuid
inids
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'sUuid
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 ofUnreferenced
, itsunreferenced
method is invoked). Ifstrong
istrue
, 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.
@author Sun Microsystems, Inc.
@since 2.0
@com.sun.jini.impl
This implementation uses the {@link Logger} namednet.jini.jeri.BasicJeriExporter
to log information at the following levels:
Level | Description |
---|---|
{@link Levels#FAILED FAILED} | incoming request forunrecognized object identifier (no such object) |
{@link Levels#FAILED FAILED} | I/O exceptiondispatching incoming request |
{@link Level#FINE FINE} | successful export of object |
{@link Level#FINE FINE} | attempted unexport of object |
{@link Level#FINE FINE} | garbage collection ofexported object |
{@link Level#FINE FINEST} | detailed implementationactivity |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|