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