java.rmi.activation.Activatable
. If you are interested in finding
out about Making a UnicastRemoteObject Activatable
or Activating an object that does not extend
java.rmi.activation.Activatable, these are also available as tutorials.
Prior to the release of the JDK1.2, an instance of a UnicastRemoteObject
could be accessed from a server program that (1) created an instance of
the remote object, and (2) ran all the time. Now with the introduction
of the class java.rmi.activation.Activatable
and the RMI daemon,
rmid
, programs can be written to register information about remote
object implementations that should be created and execute "on demand",
rather than running all the time. The RMI daemon, rmid
, provides
a JVM from which other JVM instances may be spawned.
Note: For the remainder of this tutorial, the terms
"activatable object implementation", "activatable object," and "implementation"
may be used interchangeably to refer to the class, examples.activation.ActivatableImplementation
,
which implements a remote interface and is activatable.
This tutorial is organized as follows:
Client.java
, the class which will
invoke a method on an activatable objectMyRemoteInterface.java
,
the interface that extends java.rmi.Remote
, implemented by:ActivatableImplementation.java
,
the class which will be activatedSetup.java
, the class which registers
information about the activatableFor all of the source code used in the activation tutorials, you may choose from these formats:
Creating the implementation class
For this example, the implementation class will be examples.activation.ActivatableImplementation
.
There are four steps to create an implementation class:
java.rmi.activation.Activatable
import java.rmi.*;
import java.rmi.activation.*;
Step 2:
Extend your class from java.rmi.activation.Activatable
public class ActivatableImplementation extends Activatable
implements examples.activation.MyRemoteInterface {
public ActivatableImplementation(ActivationID id, MarshalledObject
data)
throws RemoteException {
// Register the object with the activation
system
// then export it on an anonymous port
super(id, 0);
}
Step 4:
Implement the remote interface method(s)
public Object callMeRemotely() throws RemoteException {
return "Success";
}
The job of the "setup" class is to create all the information necessary
for the activatable class, without necessarily creating an instance of
the remote object. For this example the setup class will be examples.activation.Setup
.
The setup class passes the information about the activatable class to
rmid
, registers a remote reference (an instance of the activatable
class's stub class) and an identifier (name) with the rmiregistry
,
and then the setup class may exit. There are six steps to create
a setup class:
SecurityManager
ActivationDesc
instancermid
rmiregistry
import java.rmi.*;
import java.rmi.activation.*;
import java.util.Properties;
System.setSecurityManager(new RMISecurityManager());
Step 3:
Create an ActivationDesc
instance
In the setup application,the job of the activation descriptor is to
provide all the information that rmid
will require to create a
new instance of the implementation class.
Note: In order to run this code on your system, you'll need to change the file URL location to be the location of the directory on your system, where you've installed the example source code.
// The "location" String specifies a URL from where the class
// definition will come when this object is requested (activated).
// Don't forget the trailing slash at the end of the URL
// or your classes won't be found.
//
String location = "file:/home/rmi_tutorial/activation/";
MarshalledObject data = null;
// The second argument to the ActivationDesc constructor will
be used
// to uniquely identify this class; it's location is relative
to the
// URL-formatted String, location.
//
ActivationDesc desc = new ActivationDesc
("examples.activation.ActivatableImplementation",
location, data);
Step 4:
Declare an instance of your remote interface and register
the activation descriptor with rmid
MyRemoteInterface mri = (MyRemoteInterface)Activatable.register(desc);
System.out.println("Got the stub for the ActivatableImplementation");
Step 5:
Bind the stub, that was returned by the Activatable.register
method, to a name in the rmiregistry
Naming.rebind("ActivatableImplementation", mri);
System.out.println("Exported ActivatableImplementation");
Step 6:
Quit the setup application
System.exit(0);
There are six steps to compile and run the code:
rmic
on the implementation classrmiregistry
rmid
Step 1:
Compile the remote interface, implementation, client
and setup classes
% javac -d . MyRemoteInterface.java
% javac -d . ActivatableImplementation.java
% javac -d . Client.java
% javac -d . Setup.java
Step 2:
Run rmic
on the implementation class
% rmic -d . examples.activation.ActivatableImplementation
In order to run this code on your system, you'll need to change the
location of the policy
file to be the location of the directory
on your system, where you've installed the example source code.
% rmiregistry -J-Djava.security.policy=/home/rmi_tutorial/activation/policy
&
Note: In this example, for simplicity, we will use a policy
file that gives global permission to anyone from anywhere. Do
not use this policy file in a production environment. For more
information on how to properly open up permissions using a java.security.polic
y
file, please refer to to the following documents:
http://java.sun.com/products/jdk/1.2/docs/guide/security/PolicyFiles.html
http://java.sun.com/products/jdk/1.2/docs/guide/security/permissions.html
registry
, either has no CLASSPATH set or has a
CLASSPATH that does not include the path to any classes that you want downloaded
to your client, including the stubs for your remote object implementation
classes.
If you start the rmiregistry
, and it can find
your stub classes in its CLASSPATH, it will ignore the server's java.rmi.server.codebase
property, and as a result, your client(s) will not be able to download
the stub code for your remote object.
java
" commandjava
", one between
the two properties, and a third one just before the word "examples
"
(which is very hard to see when you view this as text, in a browser, or
on paper).
% java -Djava.security.policy=/home/rmi_tutorial/activation/policy
-Djava.rmi.server.codebase=file:/home/rmi-tutorial/activation/ examples.activation.Setup
The codebase property will be resolved to a URL, so it must have the
form of "http://aHost/somesource/
" or "file:/myDirectory/location/
"
or, due to the requirements of some operating systems, "file:///myDirectory/location/
"
(three slashes after the "file:
").
Please note that each of these sample URL strings has a trailing "/".
The trailing slash is a requirement for the URL set by the java.rmi.server.codebase
property, so the implementation can resolve (find) your class definition(s)
properly.
If you forget the trailing slash on the property, or if the class files
can't be located at the source (they aren't really being made available
for download) or if you misspell the property name, you'll get thrown a
java.lang.ClassNotFoundException.
This exception will be
thrown when you try to bind your remote object to the rmiregistry
,
or when the first client attempts to access that object's stub. If the
latter case occurs, you have another problem as well because the rmiregistry
was finding the stubs in its CLASSPATH.
The server output should look like this:
Got the stub for the ActivatableImplementation
Exported ActivatableImplementation
The argument to the examples.activation.Client
program is the
hostname of the implementation server, in this case, "vector
".
% java examples.activation.Client vector
The client output should look like this:
Got a remote reference to the object that extends Activatable.
Making remote call to the server
Returned from remote call
Result: Success
Copyright © 1998 Sun Microsystems, Inc. All Rights Reserved.
|