Using RMI with Apache Jserv - Create the client program (the servlet) (
Page 3 of 4 )
Enabling the servlet (Booklet.java) to talk
to the remote Directory service is a fairly straightforward procedure.
Just like any other RMI client, the servlet instantiates the remote object with
a call to Naming.lookup(). After the remote object is instantiated, you
can work with the object as if it were local.
The init() and doGet() methods are the particularly
interesting methods in the Booklet servlet.
public class Booklet extends HttpServlet {
private Directory dir;
private String url;
public void init(ServletConfig config) throws ServletException {
super.init(config);
if (System.getSecurityManager() == null ) {
System.setSecurityManager(new RMISecurityManager());
String rmiRegistryHost = getInitParameter("rmiRegistryHost");
if (rmiRegistryHost == null) {
rmiRegistryHost = "localhost";
}
try {
String name = "//" + rmiRegistryHost + ":4000/addressBook";
this.dir = (Directory) Naming.lookup(name);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void doGet (HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
this.url = req.getRequestURI();
String cmd = req.getParameter("cmd");
printHeader(out);
printForm(out);
try {
if (cmd.equals("search")) {
out.println("<h4>Search Results:</h4>");
printResults(dir.search(req.getParameter("query")), out);
} else if (cmd.equals("add")) {
out.println("<h4>New Entry:</h4>");
printEntry(
dir.getEntry(
dir.addEntry(
new ClientEntry( req.getParameter("name"),
req.getParameter("email")
)
)),
out);
} else if (cmd.equals("get")) {
out.println("<h4>Directory Entry:</h4>");
printEntry(dir.getEntry(req.getParameter("key")), out);
} else if (cmd.equals("everybody")) {
out.println("<h4>Complete Directory Listing:</h4>");
printResults(dir.getEntries(), out);
}
} catch (RemoteException e) {
out.print("<h3>Error with the RMI Transport</h3>");
} catch (NullPointerException e) {
out.println("Search for an entry, create an entry, " +
"or get an entry using the forms on the left.");
e.printStackTrace();
}
printFooter(out);
}
// rest of servlet methods....
}
Upon initialization, the servlet first checks the
SecurityManager and sets it if needed. Next, the servlet checks for the
initialization parameter named "rmiRegistryHost", the name of the computer
hosting the RMI registry to which the
Directory service is bound. To
specify the
rmiRegistryHost, in your servlet zone's properties file,
insert this line:
servlet.client.Booklet.initArgs=rmiRegistryHost=<machineName>
If this arguement is not defined, the
getInitParameter() method will return
null and the
rmiRegistryHost will be set to the localhost. Then the
init()
method obtains the
Directory service with
Naming.lookup(), and
stores it in a private variable, keeping it around for reuse. If the remote
service was obtained inside a service method, like
doGet(), the servlet
would have to obtain the remote object with every request, an expensive
procedure where repeating it should be minimized. Instead, one instance of the
remote directory service will be reused for the lifetime of the servlet.
The doGet() method, then services the incoming requests to the
servlet. It examines the parameters passed to it from the HTML form and then
calls the appropriate methods on the remote Directory service.
Nothing particularly special needs to be done in compiling the client
classes; just use the basic java compiler, javac.
$ javac client/*.java
Windows:
> javac client\*.java
Make the JAR files
Now we're going to bundle our classes into JAR files. While not an absolute
requirement, this eases the deployment step as well as distribution. At the
command prompt, type:
$ jar -cvf client.jar client/*.class directory/*.class server/AddressBook_Stub.class
on Windows operating systems the slashes change to
backslashes:
> jar -cvf client.jar client\*.class directory\*.class server\AddressBook_Stub.class
The "
c" tag tells the
jar tool to create a
new file. The "
v" tag turns on verbose output, so you can see exactly
what the jar tool is doing. The "
f" tag tells the jar tool that you
will specify the name of the jar file to be created, which is the argument
following the "
f" tag,
client.jar. The next arguments specify
which files should go into the jar file.
On the client side, the only the stub class is absolutely necessary for RMI
communication to work.
Create the server jar file:
$ jar -cvf server.jar server/*.class directory/*.class
Windows:
> jar -cvf server.jar server\*.class directory\*.class
On the server side, both stub and skeleton classes generated
by
rmic are necessary.
Deploy the classes in Jserv
So far, the steps in this article have followed the procedures described in
Sun's RMI tutorial or the Javadoc. The only really Jserv specific part is the
deployment. Installation of the client servlet is fairly straight forward:
Of course, this is assuming you already have a
servlet zone set up. If the RMI registry is going to be running on a different
computer, then specify the
rmiRegistryHost parameter for the servlet as
described above. (If you need help with setting up Apache Jserv, check out Ari
Halberstadt's
Using Apache Jserv 1.0,
http://www.servletcentral.com/1999-01/jserv.dchtml.)
Now restart your Apache Jserv server to ensure that the client.jar
file is accessible and the configuration changes take effect. Typically, an
"apachectl restart" will do it.
Run it!
Now that the client has been deployed, the all that's left to do is to run
the demo. First fire up the server (making sure that the server.jar file is in
your classpath...):
java -classpath=$CLASSPATH:/path/to/server.jar \
-Djava.security.policy=java.policy server.AddressBook
Windows:
java -classpath=%CLASSPATH%;\path\to\server.jar
-Djava.security.policy=java.policy server.AddressBook
The server should start, printing status messages to the
console.
$ java server.AddressBook
Creating RMIRegistry...
Creating Address Book...
Address Book created ...
Populating AddressBook...
Added entry: Jeff
Added entry: Leonardo
Added entry: Jose Alexis
Added entry: Walter
Added entry: Chris
The
-Djava.security.policy=java.policy parameter
tells the Java virtual machine to use the security rules specified in the
java.policy file. The file tells the JVM to accept all
socket connections on ports above 1024. This parameter is necessary otherwise
other machines won't be able to connect to the rmiregistry.
In a web browser, go to the url which maps to the client.Booklet
servlet. For a typical setup, this might be
http://yourhost/servlets/client.Booklet. If you want to
abbreviate the URL & not refer to the servlet by it's package, in your
zone.properties file, you could add:
servlet.booklet.code=client.Booklet
This creates an alias for the
client.Booklet
servlet; it's nick name is "booklet". Now you can access the Booklet servlet
with a URL something like,
http://yourhost/servlets/booklet,
instead.
The servlet will return a form to your browser which will allow you to
interact (search, add entries, select an entry, get all entries) with the
AddressBook through the HTML form.
As you interact with the AddressBook via the servlet, status messages on what
the AddressBook is doing should appear in the console in which it was started.
...
All entries retrieved...
Added entry: John
Retrieved entry: John
Queried on:Leo