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