Setup ProgramThis tutorial describes how to write a program that registers an
activation descriptor for a 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.
This tutorial has the following steps:
The files needed for this tutorial are:Setup.java - main
Setup programsetup.policy -
security policy file for the Setup programrmid.policy -
security policy file for rmidgroup.policy -
security policy file for the activation groupSetup
programThe Setup program, implemented by the class
examples.activation.Setup, registers an activation
descriptor with rmid to enable future activation of
the object specified by that activation descriptor. This program
does not create an instance of a remote object, but instead
registers a remote object's stub with an rmiregistry
so that clients can look it up. This Setup program
must be run prior to running any of the clients described in the
other activation tutorials.
The Setup program uses a number of system
properties to customize the information that is registered with
rmid and rmiregistry. The program also
takes a single command-line argument that specifies the
package-qualified name of the implementation class for the
activatable remote object being registered. The Setup
program is run as follows:
java -cp classpath \
-Djava.security.policy=setup.policy \
-Djava.rmi.server.codebase=codebase \
-Dexamples.activation.setup.codebase=setupCodebase \
-Dexamples.activation.impl.codebase=implCodebase \
-Dexamples.activation.name=name \
[-Dexamples.activation.file=filename] \
[-Dexamples.activation.policy=group.policy] \
examples.activation.Setup implClass
where:
Setup program and the implementation classesSetup programSetup program class (used in granting permissions to
the Setup program in the setup.policy
file)group.policy), andThe following is an example policy file for the
Setup program:
grant codeBase "${examples.activation.setup.codebase}" {
// permissions to read system properties required by setup program
permission java.util.PropertyPermission "examples.activation.impl.codebase","read";
permission java.util.PropertyPermission "examples.activation.policy","read";
permission java.util.PropertyPermission "examples.activation.file","read";
permission java.util.PropertyPermission "examples.activation.name","read";
// permission to connect to the activation system and the registry
permission java.net.SocketPermission "*:1098-1099","connect";
};
The codebase to which permissions are granted is a URL
specifying the location of the Setup program's
implementation class(es). This URL is the value of the
examples.activation.setup.codebase system property,
which is defined when the Setup program is run. The
Setup program needs the following permissions:
java.util.PropertyPermission - to read various
system properties required by the Setup programjava.net.SocketPermission - to connect to the
activation system (port 1098) to register an
activation descriptor, and to connect to the registry (port
1099) to bind the activatable object's stub to a
nameThere are several steps to writing this Setup
program:
rmiregistryThe Setup class has a static main
method that performs all of the above steps. But before doing so,
the main method sets a SecurityManager
and obtains the single command line argument that specifies the
package-qualified name of the implementation class for the
activatable remote object. The rest of the steps are described
below. See Setup.java for
the full source code.
Before an application registers information about a particular
activatable remote object, it first needs to register information
about the activation group that the object will be
contained in. An activation group is a container virtual
machine (VM) for a set of activatable objects. Each activation
group manages the execution of one or more activatable objects. An
activation group descriptor contains information that the
activation system needs to start an activation group's VM. An
application can register an activation group descriptor with the
activation system rmid to obtain an activation group
ID to use for the activatable object, or the application can use an
activation group ID obtained from a previous group
registration.
The activation group descriptor, an instance of the class
java.rmi.activation.ActivationGroupDesc, can be
constructed in several ways. This tutorial uses the two parameter
constructor
ActivationGroupDesc(Properties,CommandEnvironment).
The Properties map contains overrides for system
properties in the activation group VM. For this tutorial, an
activation group VM needs the following system properties
defined:
java.security.policy - the group's security policy
filejava.class.path - a dummy class path to prevent an
activation group from loading implementation classes from the local
class pathexamples.activation.impl.codebase - the location
of the implementation classes, which the group's policy file uses
to grant permissions toexamples.activation.file - a file containg the
object's persistent stateThe java.security.policy property is specified by
the examples.activation.policy system property, and
defaults to the file named group.policy which will, in
practice, be in the working directory where rmid is
run. The java.class.path property is defined as
no_classpath. The
examples.activation.impl.codebase and
examples.activation.file properties are specified by
their current values (respectively), defined when the
Setup program runs.
The group descriptor is constructed as follows:
String policy =
System.getProperty("examples.activation.policy", "group.policy");
String implCodebase =
System.getProperty("examples.activation.impl.codebase");
String filename =
System.getProperty("examples.activation.file", "");
Properties props = new Properties();
props.put("java.security.policy", policy);
props.put("java.class.path", "no_classpath");
props.put("examples.activation.impl.codebase", implCodebase);
if (filename != null && !filename.equals("")) {
props.put("examples.activation.file", filename);
}
ActivationGroupDesc groupDesc = new ActivationGroupDesc(props, null);
The following is an example group.policy file that
grants the appropriate permissions for the activation examples:
grant codeBase "${examples.activation.impl.codebase}" {
// permission to read and write object's file
permission java.io.FilePermission "${examples.activation.file}","read,write";
// permission to listen on an anonymous port
permission java.net.SocketPermission "*:1024-","accept";
};
The codebase to which permissions are granted is a URL
specifying the location of the activatable object's implementation
classes. This URL is the value of the
examples.activation.impl.codebase system property,
which will be defined in the activation group's VM. An activatable
object in the group needs two permissions:
java.io.FilePermission - to read and write the
file containing the activatable object's persistent statejava.net.SocketPermission - to export the
activatable object to accept connections an anonymous portSetup program must register the activation
group descriptor with the activation system to obtain the group's
ID, an instance of the class
java.rmi.activation.ActivationGroupID. The class
java.rmi.activation.ActivationGroup has a static
method getSystem for obtaining the stub for the
activation system. The Setup program calls the
activation system's remote method registerGroup,
passing the group descriptor created above, to register the
activation group:
ActivationGroupID groupID =
ActivationGroup.getSystem().registerGroup(groupDesc);
Once the activation group ID is obtained, the Setup
program can register the activation descriptor. The activation
descriptor has four basic pieces of information:
In this example, the activation group ID is the one obtained
above; the implementation's class name is the class name,
implClass, supplied as the command-line
argument to the Setup program; the location (URL) is
specified by the system property
examples.activation.impl.codebase; and, the
initialization data (which is optional) is a filename specified by
the system property examples.activation.file.
The activation descriptor is constructed as follows:
MarshalledObject data = null;
if (filename != null && !filename.equals("")) {
data = new MarshalledObject(filename);
}
ActivationDesc desc =
new ActivationDesc(groupID, implClass, implCodebase, data);
Next, the Setup program must register the
activation descriptor with the activation system. The class
Activatable has a static convenience method,
register, that registers an activation descriptor with
the activation system and returns a stub for the activatable object
specified by the descriptor.
Remote stub = Activatable.register(desc);
Note: The register method attempts
to load a stub class for the implementation class in order to
create a stub instance. If
the register method is unable to load a pregenerated
stub class, it will use an instance of a dynamically-generated
proxy class that implements all the interfaces of the
implementation class. In the latter case the register
method needs load the implementation class in order to
determine the remote interfaces that the implementation class
implements. So, the register method has a slight
behavioral difference, depending on whether a pregenerated or
dynamically-generated stub class is used.
rmiregistryFinally, the remote object's stub is bound to a name in the
registry running on the default port of 1099. The name
is specified by the system property
examples.activation.name.
String name = System.getProperty("examples.activation.name");
LocateRegistry.getRegistry().rebind(name, stub);
The source file for this example can be compiled as follows:
javac -d setupDir Setup.javawhere setupDir is the root destination directory to put the class files in.
rmid,
rmiregistry, and the Setup programTo run this the Setup program, you will need to do
the following:
rmidTo start rmid, run the rmid command on
the server's host. This command should produce no output if it is
run with a security policy file as specified below. For more
information, see the tools documentation for rmid
[Solaris, Linux, or Mac OS X, Windows].
For example, in the Solaris Operating System:
rmid -J-Djava.security.policy=rmid.policy \
-J-Dexamples.activation.policy=group.policy &
Or, on Windows platforms:
start rmid -J-Djava.security.policy=rmid.policy \
-J-Dexamples.activation.policy=group.policy
where:
rmidrmid's policy fileThe security policy file for rmid grants
permissions for rmid to execute specific commands and
to use specific command-line options in starting activation group
VMs. For example, a user might grant specific permissions to start
an activation group VM with one or more system properties or other
java command-line options. This example allows
rmid to start activation group VMs that define the
system properties java.security.policy,
java.class.path,
examples.activation.impl.codebase, and
examples.activation.file. The following example
security policy file grants permission to start an activation group
VM with these specific properties defined:
grant {
// allow activation groups to use certain system properties
permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=${examples.activation.policy}";
permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.class.path=no_classpath";
permission com.sun.rmi.rmid.ExecOptionPermission "-Dexamples.activation.impl.codebase=*";
permission com.sun.rmi.rmid.ExecOptionPermission "-Dexamples.activation.file=*";
};
The first ExecOptionPermission permission grant
restricts the java.security.policy system property to
be the file specified by the system property
examples.activation.policy, defined when
rmid is run. The next permission grant allows a group
to define the system property java.class.path as
no_classpath, a dummy class path that prevents the
group from having a valid class path. The next permission grant
allows the group to define the system property
examples.activation.impl.codebase to be any value. The
final permission grant allows the
examples.activation.file system property to be any
value.
rmiregistryTo start the registry, run the rmiregistry command
on the server's host. This command produces no output (when
successful) and is typically run in the background. For more
information, see the tools documentation for
rmiregistry [Solaris, Linux, or Mac OS X, Windows].
For example, in the Solaris Operating System:
rmiregistry &
Or, on Windows platforms:
start rmiregistry
By default, the registry runs on TCP port 1099. To start a registry on a different port, specify the port number from the command line. For example, to start the registry on port 2001 on a Windows platform:
start rmiregistry 2001
Note: Make sure that rmiregistry does not
have any implementation classes in its class path to prevent it
from loading any classes from its local class path.
If the registry will be running on a port other than 1099,
you'll need to specify the port number in the calls to
LocateRegistry.getRegistry in the Setup
program, as well as any clients that access this registry. For
example, if the registry is running on port 2001 in this example,
the call to getRegistry would be:
Registry registry = LocateRegistry.getRegistry(2001);
Also note that if you use a registry port other than
1099, you will also need to modify the
Setup and client program's policy files to grant
permission to connect to the registry's port.
Setup programTo start the Setup program, run the
Setup class using the java command as
follows:
java -cp setupDir:implDir \
-Djava.security.policy=setup.policy \
-Djava.rmi.server.codebase=codebase \
-Dexamples.activation.setup.codebase=setupCodebase \
-Dexamples.activation.impl.codebase=implCodebase \
-Dexamples.activation.name=name \
[-Dexamples.activation.file=file] \
[-Dexamples.activation.policy=group.policy] \
examples.activation.Setup implClass
where:
Setup program's classSetup programSetup program class (used in granting permissions to
the Setup program in the setup.policy
file)data in the object's activation descriptor (no
default)group.policy), andNote: If you use file URLs for any of the codebases listed above, make sure that each file URL has a trailing slash, or the codebase will be invalid.
The output from the Setup program should look like
this:
Activation group descriptor registered. Activation descriptor registered. Stub bound in registry.