public final class BasicJeriExporter extends Object implements Exporter
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:
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. 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.
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:
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 thatUuidon 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 thatUuidinidsis 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'sUuidis 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
Uuidon 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 thatUuidinidsis 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'sUuidis 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, itsunreferencedmethod is invoked). Ifstrongistrue, 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
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.
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 and Description |
|---|
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. |
| Modifier and Type | Method and Description |
|---|---|
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. |
public BasicJeriExporter(ServerEndpoint se, InvocationLayerFactory ilf)
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.se - the server endpoint over which calls may be acceptedilf - the factory for creating the remote object's
proxy and invocation dispatcherNullPointerException - if se or ilf
is nullpublic BasicJeriExporter(ServerEndpoint se, InvocationLayerFactory ilf, boolean enableDGC, boolean keepAlive)
BasicJeriExporter with the given server
endpoint, invocation layer factory, enableDGC flag, and
keepAlive flag. The object identifier is chosen by
invoking UuidFactory.generate.se - the server endpoint over which calls may be acceptedilf - the factory for creating the remote object's
proxy and invocation dispatcherenableDGC - if true, DGC is enabled to the object
on this server endpointkeepAlive - if true, the VM is kept alive
while the object (exported via this exporter) remains
exportedNullPointerException - if se or ilf
is nullpublic BasicJeriExporter(ServerEndpoint se, InvocationLayerFactory ilf, boolean enableDGC, boolean keepAlive, Uuid id)
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.se - the server endpoint over which calls may be acceptedilf - the factory for creating the remote object's proxy
and invocation dispatcherenableDGC - if true, DGC is enabled to the object
on this server endpointkeepAlive - if true, the VM is kept alive
while the object (exported via this exporter) remains
exportedid - an object identifier or nullNullPointerException - if se or ilf
is nullpublic ServerEndpoint getServerEndpoint()
public InvocationLayerFactory getInvocationLayerFactory()
InvocationLayerFactory for this
exporter.public boolean getEnableDGC()
true if DGC is enabled on the server endpoint to
the object corresponding to this exporter; otherwise
returns false.true if DGC is enabled;
false otherwisepublic boolean getKeepAlive()
true if the virtual machine is kept alive while
the object corresponding to this exporter is exported; otherwise
returns false.true if VM is kept alive while object is
exported; false otherwisepublic Uuid getObjectIdentifier()
public Remote export(Remote impl) throws ExportException
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:
checkPermissions on the supplied listen endpoint.
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.
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.
export in interface Exporterimpl - a remote object to exportExportException - 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 objectNullPointerException - if impl is nullIllegalStateException - if an object has already been exported
with this Exporter instanceSecurityException - if invoking the
checkPermissions method on any of the listen
endpoints throws a SecurityExceptionStartablepublic boolean unexport(boolean force)
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.
unexport in interface Exporterforce - 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 progresstrue if the remote object is unexported when
this method returns and false otherwiseIllegalStateException - if an object has not been exported
with this Exporter instanceCopyright 2007-2013, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.