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 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
.
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 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.
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 null
public 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 null
public 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 null
NullPointerException
- if se
or ilf
is null
public 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 Exporter
impl
- 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 null
IllegalStateException
- if an object has already been exported
with this Exporter
instanceSecurityException
- if invoking the
checkPermissions
method on any of the listen
endpoints throws a SecurityException
Startable
public 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 Exporter
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 progresstrue
if the remote object is unexported when
this method returns and false
otherwiseIllegalStateException
- if an object has not been exported
with this Exporter
instance