SDSU CS 696 Emerging Technologies: Distributed Objects
Spring Semester, 1998
RMI and Web

To Lecture Notes Index
© 1998, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 21-Apr-98

Contents of Doc 17, RMI and Web

  1. References
  2. Jar Files
  3. RMI Hello World via Web
    1. Example - No Jar
      1. Hello.java
      2. HelloServer.java
      3. HelloApplet.java - The client
      4. hello.html
    2. File Structure, URL Etc.
    3. Example - With Jar
      1. helloJar.html
  4. RMI and Browsers
    1. Activator Tags for IE
    2. Activator Tags for Netscape
    3. Activator Tags for Netscape and IE
  5. Bootstraping the Client
    1. java-rmi.cgi
    2. Loading the client
    3. LoadClient.java
    4. MySecurityManager.java
    5. HelloClient.java
  6. RMI and Firewalls

References


Java RMI Specification
Java RMI: Remote Method Invocation by Downing, IDG Books, 1998, Appendix A, pp 259-260

See http://www.dsu.edu/doc/jdk1.1/docs/tooldocs/solaris/jar.html for the documentation on using the jar command

Information about applet tags can be found at:
http://jva.sun.com/products/jdk/1.1/docs/guide/misc/applet.html

Information about Activator tags can be found at:
http://developer.javasoft.com/developer/earlyAccess/activator/ja-tag.html

Doc 17, RMI and Web Slide # 2

Jar Files


A jar file is basically a files that are zipped into one file with a manifest, or table of contents

The jar program allows you to bundle Java classes together

This can be useful in distributing programs like RMI clients

See http://www.dsu.edu/doc/jdk1.1/docs/tooldocs/solaris/jar.html for the documentation on using the jar command


Doc 17, RMI and Web Slide # 3
Example of Using jar
Directory Structure on Rohan


package jarExample;

public class HiMom
   {
   public void message()
      {
      System.out.println( "Hi Mom" );
      }
   }

package jarExample;

public class MyMain
   {
   public static void main( String[] args )
      {
      HiMom test = new HiMom();
      test.message();
      }
   }

Doc 17, RMI and Web Slide # 4
Compiling with -d option

In directory jarExampleSrc compile using:
javac -d .. *.java

The -d flag indicates the base directory to place the .class files

So we get:



Since the classes are in the jarExample package the .class files are placed in the base subdirectory jarExample


Doc 17, RMI and Web Slide # 5
Using Jar

In directory whitney I use the following command to create a jar file:
jar -cf hi.jar jarExample

Since the classes are in a package they must be stored in the jar file in the jarExample directory



I then place /home/ma/whitney/java/classes/whitney/hi.jar in my classpath

I can now run the program with:
java jarExample.MyMain

Doc 17, RMI and Web Slide # 6

RMI Hello World via Web

Example - No Jar

The Classes

Hello.java

package whitney.rmi.examples.applet;

public interface Hello extends java.rmi.Remote
   {
   String sayHello() throws java.rmi.RemoteException;
   }

HelloServer.java

package whitney.rmi.examples.applet;

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;
import java.io.IOException;
import java.rmi.server.*;
import java.net.InetAddress;
import sdsu.util.ProgramProperties;

public class HelloServer
      extends UnicastRemoteObject
      implements Hello
   {
   public HelloServer() throws RemoteException {}

   public String sayHello()
      {
      return  "Hello World from " + getHostName();
      }

   protected static String getHostName()
      {
      try
         {
         return InetAddress.getLocalHost().getHostName();
         }
      catch (java.net.UnknownHostException who)
         {
         return "Unknown";
         }
      }

Doc 17, RMI and Web Slide # 7
//HelloServer.java - Continued
   public static void main(String args[])
      {
      // Create and install a security manager
      System.setSecurityManager(new RMISecurityManager());

      try
         {
         ProgramProperties flags = 
            new ProgramProperties( args );

         int port = flags.getInt( "p", 1099 );
         String serverLabel =  "HelloServer";

         HelloServer serverObject = new HelloServer();
         Registry localRegistry = 
            LocateRegistry.createRegistry(port);

         localRegistry.rebind( serverLabel, serverObject);

         System.out.println("HelloServer bound in registry");
         }
      catch (Exception e)
         {
         System.out.println("HelloServer err: ");
         e.printStackTrace();
         }
      }
   }

Doc 17, RMI and Web Slide # 8

HelloApplet.java - The client

package whitney.rmi.examples.applet;

import java.awt.*;
import java.rmi.*;

public class HelloApplet extends java.applet.Applet
   {
   String message = "";
   public void init()
      {
      try
         {
         String serverAddress = getParameter( "server" );
         message = message + "After getParameter: ";
         Hello obj = (Hello)Naming.lookup( serverAddress );
         message = obj.sayHello();
         }
      catch (Exception e)
         {
         message += "HelloApplet exception:\n " + 
            e.getMessage();
         }
      }

   public void paint(Graphics g)
      {
      g.drawString(message, 25, 50);
      }
   }


Doc 17, RMI and Web Slide # 9

hello.html

<HTML>
<title>Hello World</title>
<center> <h1>Hello World</h1> </center>

The message from the HelloServer is:
<p>
<applet codebase="."
   code="whitney.rmi.examples.applet.HelloApplet"
   width=500 height=120>
<PARAM NAME="server" 
   VALUE="//www.eli.sdsu.edu:5555/HelloServer">
</applet>
</HTML>


Information about applet tags can be found at:
http://jva.sun.com/products/jdk/1.1/docs/guide/misc/applet.html


Doc 17, RMI and Web Slide # 10

File Structure, URL Etc.


URL to hello.html:
http://www.eli.sdsu.edu/rmi-web/hello.html

In my public html directory on www.eli in the directory
rmi-web

I have:
code.jar (for next example)
hello.html (for this example)
helloJar.html (for next example)
whitney/

In rmi-web/whitney/rmi/examples/applet I have:
Hello.classHelloServer.class
Hello.javaHelloServer.java
HelloApplet.classHelloServer_Skel.class
HelloApplet.javaHelloServer_Stub.class
HelloClient.javaHelloClient.class (for another example)

This runs accessing the URL:
http://www.eli.sdsu.edu/rmi-web/hello.html

using the appletveiwer on a Macintosh

You must type xstdcmap -all at the shell prompt before you run appletviewer and have it display on an NCD X-terminal in the BAM labs


Doc 17, RMI and Web Slide # 11

Example - With Jar


In this example all classes needed on the client side (Hello.class, HelloApplet.class, HelloServer_Stub.class) are placed in a jar file and downloaded using the archive tag

This is much faster than having the files downloaded one at a time

This example is run by accessing the URL:
http://www.eli.sdsu.edu/rmi-web/helloJar.html

helloJar.html

<HTML>
<title>Hello World</title>
<center> <h1>Hello World</h1> </center>

The message from the HelloServer is:
<p>
<applet codebase="."
   archive="code.jar"
   code="whitney.rmi.examples.applet.HelloApplet"
   width=500 height=120>
<PARAM NAME="server" VALUE="//www.eli.sdsu.edu:5555/HelloServer">
</applet>
</HTML>


Doc 17, RMI and Web Slide # 12

RMI and Browsers


To run an applet that uses RMI the browser must support RMI

There was an RMI release that worked with Java 1.0.2

Microsoft has a .zip file to use with IE4.0 to allow rmi to work with IE, see htt://www.microsoft.com/msdn/services/subscription/msdn_unsup-ed.htm
Netscape Communicator & RMI

To be done later
Activator
Sun's solution to the different browsers is Activator, which replaces the browser's Java VM with a Sun Java VM which supports java 1.1.5

See http://java.sun.com/proucts/activator/index.html for more information and to download activator

To use activator, it must be installed on the client machine and the applet tag needs to be modified


Doc 17, RMI and Web Slide # 13

Activator Tags for IE


To work with the activator for IE the applet tag:
<applet codebase="."
   code="whitney.rmi.examples.applet.HelloApplet"
   width=500 height=120>
<PARAM NAME="server" 
   VALUE="//www.eli.sdsu.edu:5555/HelloServer">
</applet>


Needs to be changed to:
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
   width="500" height="120" 
   codebase="http://java.sun.com/activator/Jinstall_ea3.cab#Version=1,0,3,0"> 
   <PARAM NAME="code" 
      VALUE="whitney.rmi.examples.applet.HelloApplet">
 
   <PARAM NAME="codebase" VALUE=".">
   <PARAM NAME="type" 
      VALUE="application/x-java-applet;version=1.1"> 

   <PARAM NAME="server" 
      VALUE="//www.eli.sdsu.edu:5555/HelloServer">
   No JDK 1.1 support for APPLET!! 
</OBJECT> 


Doc 17, RMI and Web Slide # 14

Activator Tags for Netscape


To work with the activator for Netscape the applet tag:
<applet codebase="."
   code="whitney.rmi.examples.applet.HelloApplet"
   width=500 height=120>
<PARAM NAME="server" 
   VALUE="//www.eli.sdsu.edu:5555/HelloServer">
</applet>


Needs to be changed to:
<EMBED type="application/x-java-applet;version=1.1"
    width="500" height="120" 
   code="whitney.rmi.examples.applet.HelloApplet" 
   codebase="." 
   server="//www.eli.sdsu.edu:5555/HelloServer" 
   pluginspage="http://java.sun.com/products/activator/ea3/plugin-install.html"> 
   <NOEMBED> 
      No JDK 1.1 support for APPLET!! 
   </NOEMBED> 
</EMBED> 


Doc 17, RMI and Web Slide # 15

Activator Tags for Netscape and IE


To work with the activator for IE the applet tag given on the previous slide needs to be changed to:
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
   width="500" height="120" 
   codebase="http://java.sun.com/activator/Jinstall_ea3.cab#Version=1,0,3,0"> 
   <PARAM NAME="code" 
      VALUE="whitney.rmi.examples.applet.HelloApplet">
 
   <PARAM NAME="codebase" VALUE=".">
   <PARAM NAME="type" 
      VALUE="application/x-java-applet;version=1.1"> 

   <PARAM NAME="server" 
      VALUE="//www.eli.sdsu.edu:5555/HelloServer">

   <COMMENT>
      <EMBED type="application/x-java-applet;version=1.1"
          width="500" height="120" 
         code="whitney.rmi.examples.applet.HelloApplet" 
         codebase="." 
         server="//www.eli.sdsu.edu:5555/HelloServer" 
         pluginspage="http://java.sun.com/products/activator/ea3/plugin-install.html"> 
      <NOEMBED> 
   </COMMENT>
      No JDK 1.1 support for APPLET!! 
      </NOEMBED> 
   </EMBED> 
</OBJECT> 


Doc 17, RMI and Web Slide # 16
Activator Tags for Everywhere

This get to be a bit complicated and uses javascript

For more information see:
http://developer.javasoft.com/developer/earlyAccess/activator/ja-tag.html


Doc 17, RMI and Web Slide # 17

Bootstraping the Client


In RMI you can have all the classes for the client machine downloaded from the server machine when you want to run the client

This is relatively slow

Users may not like downloading code which is then run on their machines

This requires a web server on the server machine

Most web servers require a cgi program to forward the request to the rmi system

The cgi program must be in a file called "java-rmi.cgi" and must be in top level cgi bin directory

The following java-rmi.cgi program does the forwarding
This program can be found in the rmi-users mailing list archive and Java RMI: Remote Method Invocation by Downing, IDG Books, 1998, Appendix A, pp 259-260

Doc 17, RMI and Web Slide # 18

java-rmi.cgi

#!/bin/sh
# This file handles rmi requests to download RMI code
# The work is done by the class: 
#      sun.rmi.transport.proxy.CGIHandler
# This class supports a QUERY_STRING of the form
# "forward=<port>" with a REQUEST_METHOD of "POST"
# The body of the request will be forwarded to the server (
# as aPOST request) to the port given in the URL. The response
# will be returned to the orginal requester.

# Set the path to include the location of the jdk to run
PATH=/opt/java/bin:$PATH

java   \
   -DAUTH_TYPE=$AUTH_TYPE \
   -DCONTENT_LENGTH=$CONTENT_LENGTH \
   -DCONTENT_TYPE=$CONTENT_TYPE \
   -DDOCUMENT_ROOT=$DOCUMENT_ROOT \
   -DGATEWAY_INTERFACE=$GATEWAY_INTERFACE \
   -DHTTP_ACCEPT="$HTTP_ACCEPT" \
   -DHTTP_CONNECTION=$HTTP_CONNECTION \
   -DHTTP_HOST=$HTTP_HOST \
   -DHTTP_USER_AGENT="$HTTP_USER_AGENT" \
   -DPATH_INFO=$PATH_INFO \
   -DPATH_TRANSLATED=$PATH_TRANSLATED \
   -DQUERY_STRING=$QUERY_STRING \
   -DREMOTE_ADDR=$REMOTE_ADDR \
   -DREMOTE_HOST=$REMOTE_HOST \
   -DREMOTE_IDENT=$REMOTE_IDENT \
   -DREMOTE_USER=$REMOTE_USER \
   -DREQUEST_METHOD=$REQUEST_METHOD \
   -DSCRIPT_NAME=$SCRIPT_NAME \
   -DSERVER_NAME=$SERVER_NAME \
   -DSERVER_PORT=$SERVER_PORT \
   -DSERVER_PROTOCOL=$SERVER_PROTOCOL \
   -DSERVER_SOFTWARE=$SERVER_SOFTWARE \
   sun.rmi.transport.proxy.CGIHandler


Doc 17, RMI and Web Slide # 19

Loading the client


The following program, LoadClient, bootstraps the client code for the class: whitney.rmi.examples.applet.HelloClient and then runs the client

This program is to be run on the client machine

Do not refer to any of the client classes directly in this program,

If you refer to them the class loader will try to load them from the local machine and throw an exception when it can not find them


Doc 17, RMI and Web Slide # 20

LoadClient.java

import java.rmi.RMISecurityManager;
import java.rmi.server.RMIClassLoader;
import java.net.URL;

public class LoadClient
   {
   public static void main( String[] args)
      {
      System.setSecurityManager(new MySecurityManager());

      try
         {
         URL codeBaseURL = new URL( 
            "http://www.eli.sdsu.edu/rmi-web/");
         
         String clientClassName = 
               "whitney.rmi.examples.applet.HelloClient";

         System.out.println( "Try To load class");
         Class clientClass = 
            RMIClassLoader.loadClass(codeBaseURL, 
                                    clientClassName );
         System.out.println( clientClass.getName() );
         Runnable client = (Runnable) clientClass.newInstance();
         System.out.println( "Run client");
         client.run();
         }
      catch ( Exception allErrors )
         {
         System.out.println( "LoadClient Exception: " );
         allErrors.printStackTrace();
         }
      }
   }

Doc 17, RMI and Web Slide # 21

MySecurityManager.java


This security manager allows the downloading of classes

import java.rmi.*;

public class MySecurityManager extends RMISecurityManager
{
   public synchronized void checkAccess(Thread t) {}
   public synchronized void checkAccess(ThreadGroup g) {}
   public synchronized void checkConnect(String h, int p) {}
   public synchronized void checkConnect(String h, int p, 
                                          Object o) {}
   public synchronized void checkRead(String f, Object c) {}
   public synchronized void checkRead(String f) {}
}


Doc 17, RMI and Web Slide # 22

HelloClient.java

Here is the actual client program that is run
package whitney.rmi.examples.applet;

import java.rmi.*;

public class HelloClient implements Runnable
   {
   public void run() 
      {
      try 
         {
         String server = "rmi://roswell.sdsu.edu:5555/HelloServer";

         Hello remote = (Hello) Naming.lookup( server );
         String message = remote.sayHello();
         System.out.println( message );
         } 
      catch ( Exception error) 
         {
         error.printStackTrace();
         }
      }
   }

Doc 17, RMI and Web Slide # 23

RMI and Firewalls


When a RMI connection hits a firewall, the transport layer will embed the RMI call in a HTTP POST request and the return information is sent back in the body of the HTTP response

If the firewall proxy will forward an HTTP request directed to an arbitrary port on the host machine, then request is sent to the proper RMI port
The transport layer on that port handles the decoding of the HTTP POST

If the firewall proxy will only forward an HTTP request to well-known HTTP ports, then the call will be forwarded to the HTTP (web) server listening on port 80 of the host machine
The web server will need the java-rmi.cgi program to route the connection

Connections routed through HTTP are at least an order of magnitude slower than normal connections

In JDK 1.2 you can specify which port a remote will listen on, to allow you to configure firewalls to allow RMI requests through


visitors since 10-Mar-98