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 rmid
group.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:
rmiregistry
The 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.
rmiregistry
Finally, 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:
rmid
To 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:
rmid
rmid
'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.
rmiregistry
To 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.