1<html>
2<body>
3<h2>Remote Method Invocation</h2>
4
5<P>Javassist enables an applet to access a remote object as if it is a
6local object.  The applet can communicate through a socket with the
7host that executes the web server distributing that applet.  However,
8the applet cannot directly call a method on an object if the object is
9on a remote host.  The <code>javassist.tools.rmi</code> package provides
10a mechanism for the applet to transparently access the remote object.
11The rules that the applet must be subject to are simpler than the
12standard Java RMI.
13
14<h3>1. Sample applet</h3>
15
16<P>The applet showing below is a simple number counter.
17If you press the button, the number is increased by one.
18An interesting feature of this applet is that the object
19recording the current number is contained by the web server
20written in Java.  The applet must access the object through a socket
21to obtain the current number.
22
23<p><center>
24<applet codebase="http://localhost:5001"
25code="sample.rmi.CountApplet" width=200 height=200>
26<param name=name value="counter">
27<param name=button value="+1">
28</applet>
29</center>
30
31<p>However, the program of the applet does not need to directly handle
32a socket.  The <code>ObjectImporter</code> provided by Javassist deals
33with all the awkward programming.
34Look at the lines shown with red:
35
36<p><b>Figure 1: Applet</b>
37
38<pre>
39<font color="red">import javassist.tools.rmi.ObjectImporter;</font>
40
41public class CountApplet extends Applet implements ActionListener {
42  private Font font;
43  <font color="red">private ObjectImporter importer;
44  private Counter counter;</font>
45  private AlertDialog dialog;
46  private String message;
47
48  public void init() {
49    font = new Font("SansSerif", Font.ITALIC, 40);
50    Button b = new Button(getParameter("button"));
51    b.addActionListener(this);
52    add(b);
53    <font color="red">importer = new ObjectImporter(this);</font>
54    dialog = new AlertDialog();
55    message = "???";
56  }
57
58  public void start() {
59    String counterName = getParameter("name");
60    <font color="red">counter = (Counter)importer.getObject(counterName);</font>
61    message = Integer.toString(<font color="red">counter.get()</font>);
62  }
63
64  /* The method called when the button is pressed.
65  */
66  public void actionPerformed(ActionEvent e) {
67    message = Integer.toString(<font color="red">counter.increase()</font>);
68    repaint();
69  }
70
71  public void paint(Graphics g) {
72    g.setFont(font);
73    g.drawRect(50, 50, 100, 100);
74    g.setColor(Color.blue);
75    g.drawString(message, 60, 120);
76  }
77}
78</pre>
79
80<p>A <code>Counter</code> object running on a remote host
81maintains the counter number.  To access this object, the applet first
82calls <code>getObject()</code> on an <code>ObjectImporter</code>
83to obtain a reference to the object.  The parameter is the name associated
84with the object by the web server.  Once the reference is obtained, it
85is delt with as if it is a reference to a local object.
86For example, <code>counter.get()</code> and <code>counter.increase()</code>
87call methods on the remote object.
88
89<p>The definition of the <code>Counter</code> class is also
90straightforward:
91
92<p><b>Figure 2: Remote object</b>
93
94<pre>
95public class Counter {
96  private int count = 0;
97
98  public int get() {
99    return count;
100  }
101
102  public int increase() {
103    count += 1;
104    return count;
105  }
106}
107</pre>
108
109<p>Note that the <code>javassist.tools.rmi</code> package does not require
110the <code>Counter</code> class to be an interface unlike the Java RMI,
111with which <code>Counter</code> must be an interface and it must be
112implemented by another class.
113
114<p>To make the <code>Counter</code> object available from the applet,
115it must be registered with the web server.  A <code>AppletServer</code>
116object is a simple webserver that can distribute <code>.html</code> files
117and <code>.class</code> files (Java applets).
118
119<p><b>Figure 3: Server-side program</b>
120
121<pre>
122public class MyWebServer {
123  public static void main(String[] args) throws IOException, CannotCompileException
124  {
125      AppletServer web = new AppletServer(args[0]);
126      <font color="red">web.exportObject("counter", new Counter());</font>
127      web.run();
128  }
129}
130</pre>
131
132<p>The <code>exportObject()</code> method registers a remote object
133with the <code>AppletServer</code> object.  In the example above,
134a <code>Counter</code> object is registered.  The applet can access
135the object with the name "counter".  The web server starts the service
136if the <code>run()</code> method is called.
137
138<p><br>
139
140<h3>2. Features</h3>
141
142The remote method invocation mechanism provided by Javassist has the
143following features:
144
145<ul>
146<li><b>Regular Java syntax:</b><br>
147	The applet can call a method on a remote object with regular
148	Java syntax.
149<p>
150
151<li><b>No special naming convention:</b><br>
152	The applet can use the same class name as the server-side program.
153	The reference object to a remote <code>Foo</code> object is
154	also represented by the class <code>Foo</code>.
155	Unlike other similar
156	systems, it is not represented by a different class such as
157	<code>ProxyFoo</code> or an interface implemented by
158	<code>Foo</code>.
159<p>
160
161<li><b>No extra compiler:</b><br>
162	All the programs, both the applet and the server-side program,
163	are compiled by the regular Java compiler.  No external compiler
164	is needed.
165</ul>
166
167<p> With the Java RMI or Voyager, the applet programmer must define
168an interface for every remote object class and access the remote object
169through that interface.
170On the other hand, the <code>javassist.tools.rmi</code> package does not
171require the programmer to follow that programming convention.
172It is suitable for writing simple distributed programs like applets.
173
174<p><br>
175
176<h3>3. Inside of the system</h3>
177
178<p>A key idea of the implementation is that the applet and the server-side
179program must use different versions of the class <code>Counter</code>.
180The <code>Counter</code> object in the applet must work as a proxy
181object, which transfers the method invocations to the <code>Counter</code>
182object in the server-side program.
183
184<p>With other systems like the Java RMI, the class of this proxy object is
185produced by a special compiler such as <code>rmic</code>.
186It must be manually maintained by the programmer.
187
188<center><img src="inside.gif"></center>
189
190<p>However, Javassist automatically generates the proxy class at
191runtime so that the programmer does not have to be concerned about the
192maintenance of the proxy class.
193If the web browser running the applet
194requests to load the <code>Counter</code> class, which is the class
195of an exported object,
196then the web server
197transfers the version of <code>Counter</code> that Javassist generates
198as a proxy class.
199
200<p><br>
201
202</body>
203</html>
204