ActivatableThis tutorial describes how to implement an activatable remote
object, but differs from the tutorial Using Activation: Extending
Activatable in that the implementation for the
remote object does not extend the class
java.rmi.activation.Activatable. Instead, the
implementation uses a static method of the class
Activatable to export an activatable remote object.
This tutorial uses a Setup program (described in the
tutorial Using Activation: the
Setup Program) that registers information about an
activatable remote object with the Java Remote Method Invocation (Java RMI) activation
system daemon (rmid) and then binds a stub for that
remote object in an rmiregistry so that clients can
look it up. You may want to read that tutorial before this one.
This tutorial has the following steps:
Setup programThe files needed for this tutorial are:
MyRemoteInterface.java
- a simple remote interfaceDoesNotExtendActivatable.java
- an "activatable" implementation of the remote
interfaceClient.java - a
client that uses the remote interfaceclient.policy -
the security policy file for the clientThere are a few basic ways to implement an activatable remote
object. This tutorial describes how to implement an activatable
remote object by using a static method of the class
java.rmi.activation.Activatable to export an
activatable remote object.
A remote object is activated when a client invokes a remote
method on a stub for an activatable remote object. A stub for an
activatable remote object contains the remote object's activation
ID and information on how to contact the Java RMI activation system
daemon (rmid) for the remote object. If the stub
cannot connect to the last-known address (i.e., host/port) for the
remote object, the stub will contact the remote object's activator
(rmid) to activate the object. When rmid
receives an activation request, it starts the remote object's
activation group (or container) VM if the group is not already
executing, and then rmid asks the group to make an
instance of the remote object. Once the group constructs the remote
object, it returns the remote object's stub to rmid
which, in turn, returns the actual stub to the initiating stub so
that the initiating stub can update its information on how to
contact the remote object in the future.
Before any of this activation can take place, an application
must register information about the activatable remote objects it
needs to use. The following separate tutorial describes the
information needed to activatate a remote object and how to
register this information with rmid:
In this example, the activatable remote object implements the
following remote interface
examples.activation.MyRemoteInterface:
package examples.activation;
import java.rmi.*;
public interface MyRemoteInterface extends Remote {
Object remoteMethod(Object obj) throws RemoteException;
}
The implementation class,
examples.activation.DoesNotExtendActivatable, for the
activatable remote object is as follows:
package examples.activation;
import java.rmi.*;
import java.rmi.activation.*;
public class DoesNotExtendActivatable implements MyRemoteInterface {
private final ActivationID id;
public DoesNotExtendActivatable(ActivationID id, MarshalledObject data)
throws RemoteException
{
this.id = id;
Activatable.exportObject(this, id, 0);
}
public Object remoteMethod(Object obj) {
return obj;
}
}
The class DoesNotExtendActivatable implements the
remote interface MyRemoteInterface, but does not
extend any class.
The class DoesNotExtendActivatable declares a
special "activation" constructor that an activation group
calls to construct an instance during the activation process. This
special constructor takes two parameters:
ActivationID, is an
identifier for the activatable remote object. When an application
registers an activation descriptor with rmid,
rmid assigns it an activation ID, which refers to the
information associated with the descriptor. This same activation ID
(also contained in the remote object's stub) is passed to this
constructor when the remote object is activated.MarshalledObject that
contains initialization data pre-registered with rmid.
This initialization data may be a filename for the object's
persistent state, for example. This example does not require any
initialization data to construct the remote object.The constructor saves the activation ID in a private field, and
then calls the static method Activatable.exportObject,
passing the implementation itself (this), the
activation ID, and the port number 0, indicating that
the object should be exported on an anonymous TCP port. While this
implementation does not actually use the activation ID it stores,
this example saves the activation ID to demonstrate what a typical
implementation of an activatable object might do. Such an
implementation may need the activation ID in the future, in order
to deactivate the object, for example.
Finally, the class implements the remote interface's single
method, remoteMethod to return the object passed as an
argument.
The Client program looks up a remote object's stub
(one that implements the remote interface
MyRemoteInterface) in the registry on the host
supplied as the optional first argument, and then invokes the
stub's remoteMethod method. The client program is the
same as the one described in the tutorial Using Activation: Extending
Activatable. For details, see the following
section of that tutorial
The source files for this example can be compiled as follows:
javac -d implDir MyRemoteInterface.java DoesNotExtendActivatable.java javac -d clientDir MyRemoteInterface.java Client.java
where implDir is the destination directory to put the implementation's class files the class files in, and clientDir is the destination directory to put the client's class files in.
Setup
programOnce your implementation phase is complete, you need to register
information about the activatable object so a client can use it.
The Setup program, described by the tutorial Using Activation: the Setup Program,
registers an activation descriptor for an activatable object with
rmid, and then binds the remote object's stub in an
rmiregistry so that clients can look it up.
To run the Setup program for this example, see the
section Start rmid,
rmiregistry, and the Setup program in
the setup program tutorial, which describes how to start
rmid, rmiregistry, and the
Setup program itself.
After you run rmid and rmiregistry as
instructed in the Setup tutorial, you will need to run
the Setup program to register an activation descriptor
for an activatable object that implements the class
examples.activation.DoesNotExtendActivatable. The
following command line runs the Setup program,
supplying an appropriate file URL for each codebase used:
java -cp setupDir:implDir \
-Djava.security.policy=setup.policy \
-Djava.rmi.server.codebase=file:/implDir/ \
-Dexamples.activation.setup.codebase=file:/setupDir/ \
-Dexamples.activation.impl.codebase=file:/impDir/ \
-Dexamples.activation.name=examples.activation.MyRemoteInterface \
-Dexamples.activation.policy=group.policy \
examples.activation.Setup examples.activation.DoesNotExtendActivatable
where:
Setup program's classSetup programNote that the examples.activation.file system
property does not need to be specified, because the
DoesNotExtendActivatable implementation class does not
use it. Also note that each file URL above has the required
trailing slash. Examples of group and setup policy files, suitable
for this tutorial, are described in the setup tutorial, and are
also listed below:
The output from the Setup program should look like
this:
Activation group descriptor registered. Activation descriptor registered. Stub bound in registry.
Once you have successfully registered an activation descriptor
for a DoesNotExtendActivatable implementation, you can
run the client program, which, during its first execution, will
cause the activatable object to activate.
The client program is the same as the one described in the
tutorial Using Activation: Extending
Activatable. For details, see the following
section of that tutorial: