(Remote Method Invocation) : Sang Shin Java Technology Evangelist
(Remote Method Invocation) : Sang Shin Java Technology Evangelist
Topics
What is RMI? Why RMI? Architectural components Serialization & Marshaled Objects Dynamic class loading Code movement Codebase ClassLoader delegation RMI Security Writing RMI Server and Client Activation HTTP Tunneling
What is RMI?
What is RMI?
RPC (Remote Procedure Call) between Java Objects General RPC behavior
Invoke
remote methods Pass arguments into methods Receive results from methods
RPC Evolution
Non-object-oriented
What is RMI?
movement semantics Built-in security mechanism Exposure of network failures to application programmers through RemoteException
Why RMI?
Capitalizes on the Java object model Minimizes complexity of distributed programming Uses pure Java interfaces
no
Preserves safety of Java runtime Recognizes differences of remote call from local call
partial
Remote Interface
Java interface
Specify
Implemented by a class, an instance of which becomes a remote object Contract between caller of the remote method (RMI client) and remote object (RMI server) Extends java.rmi.Remote interface
Markup
interface
9
Gets created from RMI server implementation (not from RMI interface)
11
RMI Stub
Resides in callers local address space Represents remote object to caller (client)
Plays the role of proxy of remote object Implementation of Remote interface Caller invokes methods of RMI Stub locally
Connects to the remote object Sends arguments to and receive results from remote object
RMI Skeleton
Resides
in servers address space Receives arguments from caller (RMI Client's Stub) and send results back to caller Performs marshaling and unmarshaling Figures out which method of remote object to be called In JDK 1.3, RMI Skeleton gets created automatically via reflection
13
Remote Object
Caller
Remote Interface
Remote Object
Stub
Skeleton
16
17
Caller (Client)
1. invokes
the method call 2. marshals the arguments 3. makes calls to remote object
18
Remote object
1. Receives
the calls via Skeleton 2. Unmarshals the arguments 3. Performs the call locally 4. Marshals the result 5. Send the result to client
Stub
1. Receives
19
Serialization in RMI
Marshaling is a process of encoding objects to put them on the wire Unmarshaling is the process of decoding from the wire and placing object in the address space RMI uses Java programming lanaguage's serialization and deserialization to perform marshaling and unmarshaling
These
21
Serialization in RMI
Arguments/Results get serialized before being transported by sender Arguments/Results get deserialized after being transported by receiver Arguments/Results in RMI can be one of the following two
Remote
22
Serialization in RMI
interface type Stub gets serialized (instead of remote object itself) Pass by reference semantics
serialized copy of the object Should be type of java.io.Serializable Pass by Value semantics
23
Example
// Arguments and Returns are non-remote objects public interface SayHelloStringRemote extends Remote { public String SayHelloString (String message) throws RemoteException; } // Arguments has both remote and non-remote objects public interface SayHelloObjectRemote extends Remote { public String SayHelloObject (String messsage, SayHelloStringRemote someName) throws RemoteException; }
24
Serialization
files)
Serialization
Serialized copy defines state Class files define behavior Both can be moved around over the network
Collectively
26
Marshaled Objects
Used when you want to maintain the serialized object without deserializing it immediately
Storage
service of objects
28
Lookup service
Serialized
30
By the exporter of the class Via Export codebase (RMI codebase) property
java.rmi.server.codebase Typically
31
32
Both client and server have RMI Remote interface class in their local classpaths Server has HelloWorld_Stub class in its local classpath Client does not have HelloWorld_Stub class in its localpath
He
typically does not have HelloWorld_Stub class in its local classpath So it will read the RMI codebase annotation (from the serialized stub object) and will try to download the HelloWorld_Stub class from the location specified in codebase annotation
34
service
Moved
Code
Represented
by class files
Data
Represented
Contains
Values
of the fields of the object Name of the class Location of the class
Via codebase annotation performed by the exporter of the class RMI codebase property
Codebase
What is Codebase?
40
Import codebase
codebase
your local VM uses to load classes it needs specified via CLASSPATH or -cp option
remote VMs use to obtain the class files "exported" from your local VM specified via java.rmi.server.codebase property
Codebase annotation 41
When a client instantiates the object, the bytecodes of the class will be downloaded by RMIClassloader from the location specified as RMI codebase
42
(Recommended)
(Not recommended)
path
43
RMI codebase
Stub classes for remote objects Interface classes of remote objects If client has the classes in its local classpath, no downloading occurs Any classes that are needed by the interface and stub classes
server
Same as above
44
45
Lookup service
46
jini-examples-dl.jar
Lookup browser (as Lookup service client) exports classes needed by Lookup service
0 .. META-INF/ 66 .. META-INF/MANIFEST.MF 2003 .. com/sun/jini/example/browser/ Browser$Listener_Stub.class 2015 .. com/sun/jini/example/browser/ ServiceEditor$NotifyReceiver_Stub.class 1045 .. net/jini/core/event/RemoteEvent.class 376 .. net/jini/core/event/RemoteEventListener.class 389 .. net/jini/core/event/UnknownEventException.class
47
RMI codebase was set, but HTTP server is not running RMI codebase was set, HTTP server is running, but the class is not present under the proper path in HTTP server The port number on which HTTP server is listening is not the same as the port number in the RMI codebase The name of the host on which HTTP server is running is not the same as the hostname in the RMI codebase If a non-jar URL is being used in the RMI codebase, there is no trailing slash (if class file location is in a jar file, no trailing slash is required)
48
Client could not download the stub class from the server The error message could be misleading in JDK 1.2 (Fixed in JDK 1.3)
The problem could be that the stub class itself is downloadable but other classes that the stub needs are not downloadable Use javap -classpath <path1:path2> <classname>
49
Server could not download the remote event listener stub class from the client
See if stub was generated correctly (via RMIC) See if listener object was exported (via .exportObject() method) See if RMI codebase is set correctly by the client
50
Things are working fine but when client and server are on different machines, I get ClassNotFoundException
Very
likely due to the fact that the class files are not available anymore
Do not use CLASSPATH for downloadable files
Do use RMI codebase
It depends
52
The Stub file is definitely being exported. And HTTP server is up and running OK. Yet, the client still complains ClassNotFoundException on Stub file under JDK 1.2
This is typically due to the fact that the class file that the stub file needs is not being exported Use javap command to find out which class file is really missing
53
Implementation Guideline
Client has remote interface class file in its local classpath (unless it uses reflection) The classes that are needed for implementation should be downloadable from the server
Needed when client does not have interface classes in its local path
Example
[daydreamer] java -Djava.security.policy=/home/sang/src/examples/lease/policyEventGenerator -Djava.rmi.server.codebase=http://daydreamer:8081/EventGenerator-srvc-dl.jar http://daydreamer:8081/EventGenerator-attr-dl.jar -jar /home/sang/jars/EventGenerator.jar daydreamer [daydreamer] jar -tvf EventGenerator-srvc-dl.jar 0 Mon Mar 22 13:04:56 EST 1999 META-INF/ 66 Mon Mar 22 13:04:56 EST 1999 META-INF/MANIFEST.MF 982 Mon Mar 22 13:04:04 EST 1999 examples/eventg/EventGenerator.class 7933 Mon Mar 22 13:04:20 EST 1999 examples/eventg/EventGeneratorImpl_Stub.class 1532 Mon Mar 22 13:03:52 EST 1999 examples/eventg/TestLease.class 911 Mon Mar 22 13:03:52 EST 1999 examples/eventg/TestLeaseMap.class 1554 Mon Mar 22 13:04:00 EST 1999 examples/eventg/TestEventLease.class 967 Mon Mar 22 13:04:00 EST 1999 examples/eventg/TestEventLeaseMap.class 410 Mon Mar 22 13:03:56 EST 1999 examples/eventg/TestEvent.class [daydreamer] jar -tvf EventGenerator-attr-dl.jar 0 Mon Mar 22 13:05:14 EST 1999 META-INF/ 66 Mon Mar 22 13:05:14 EST 1999 META-INF/MANIFEST.MF 752 Mon Mar 22 13:05:10 EST 1999 net/jini/lookup/entry/ServiceInfo.class 1764 Mon Mar 22 13:05:12 EST 1999 com/sun/jini/lookup/entry/BasicServiceType.class
55
Deployment Tips
56
Trouble-shooting methods
Run HTTP server in verbose mode (Example next slide) Will display all the jar or class files being downloaded Set -Djava.rmi.loader.logLevel=VERBOSE on RMI client (Example next slide) Will tell which class file is being downloaded from which location Try javap -classpath <pathlist or jar files> <classname> on command line (Example next slide) Will tell what is really missing See if you can access the jar file using a browser Save as dialog box pops up if the file is accessible Try FTP URL notation (instead of HTTP) If it works, HTTP has a problem
57
58
-Djava.rmi.loader.logLevel=VERBOSE
[daydreamer] java -Djava .security.policy=/home/sang/src/examples/client/policyLookupSrvcAndInvoke -Dsun.rmi.loader.logLevel=VERBOSE -jar /home/sang/jars/LookupSrvcAndInvoke.jar daydreamer groupsWanted[0] = daydreamer Waiting For Discovery to Complete Wed Mar 17 07:43:01 EST 1999:loader:unicast discovery:LoaderHandler.loadClass: loading class "com.sun.jini.reggie.RegistrarProxy" from [http://daydreamer:8080/reggie-dl.jar] .Wed Mar 17 07:43:02 EST 1999:loader:unicast discovery:LoaderHandler.loadClass: loading class "com.sun.jini.reggie.RegistrarImpl_Stub" from [http://daydreamer:8080/reggie-dl.jar] LookupDiscoveryListener: discovered... Lookup on host jini://daydreamer/: regGroups[0] belongs to Group: myGroup regGroups[1] belongs to Group: daydreamer ........... Discovery of Available Lookups Complete. Query each Lookup for known Services, the Invoke ... Lookup Service on Host: jini://daydreamer/ Belongs to Group: daydreamer Wed Mar 17 07:43:13 EST 1999:loader:main:LoaderHandler.loadClass: loading class "com.sun.jini.lookup.entry.BasicServiceType" from [http://daydreamer:8080/reggie-dl.jar] Wed Mar 17 07:43:13 EST 1999:loader:main:LoaderHandler.loadClass: loading class "net.jini.lookup.entry.ServiceInfo" from [http://daydreamer:8080/reggie-dl.jar] Wed Mar 17 07:43:13 EST 1999:loader:main:LoaderHandler.loadClass: loading class "com.sun.jini.lookup.entry.BasicServiceType" from [http://daydreamer:8080/sun-util.jar, http://daydreamer:8081/RegRemoteAndProvideLease-srvc-dl.jar, http://daydreamer:8081/RegRemoteAndProvideLease-attr-dl.jar] Wed Mar 17 07:43:13 EST 1999:loader:main:LoaderHandler.loadClass: loading class "net.jini.lookup.entry.ServiceInfo" from [http://daydreamer:8080/sun-util.jar, http://daydreamer:8081/RegRemoteAndProvideLease-srvc-dl.jar, http://daydreamer:8081/RegRemoteAndProvideLease-attr-dl.jar]
59
javap
[daydreamer:291] javap -classpath LookupSrvcAndInvoke.jar examples/lease/TestLease Class 'examples/lease/TestLease' not found [daydreamer:289] javap -classpath RegRemoteAndProvideLease-srvc-dl.jar examples/lease/TestLease Error: No binary file 'AbstractLease [daydreamer:326] javap -classpath RegRemoteAndProvideLease.jar:sun-util.jar examples/lease/TestLease Error: No binary file 'Lease' [daydreamer:332] javap -classpath RegRemoteAndProvideLease.jar:sun-util.jar:jini-core.jar examples/lease/TestLease Compiled from TestLease.java public class examples/lease/TestLease extends com.sun.jini.lease.AbstractLease { protected final examples.lease.RegRemoteAndProvideLease server; protected final java.lang.String leaseID; protected examples/lease/TestLease(examples.lease.RegRemoteAndProvideLease,java.lang.String,long); public boolean canBatch(net.jini.core.lease.Lease); public void cancel() throws net.jini.core.lease.UnknownLeaseException, java.rmi.RemoteException; public net.jini.core.lease.LeaseMap createLeaseMap(long); public long doRenew(long) throws net.jini.core.lease.UnknownLeaseException, java.rmi.RemoteException; java.lang.String getLeaseID(); examples.lease.RegRemoteAndProvideLease getRegRemoteAndProvideLease(); void setExpiration(long); }
60
javap
admin/AdminServer registers with a lookup service without including OurOwnAdmin class file in its downloadable jar You will see unknown service on the Lookup browser
[daydreamer:230] cd ~sang/jars [daydreamer:232] ls -lat Admin* -rw-rw---- 1 sang jinieast 8035 Mar 22 21:19 AdminClient.jar -rw-rw---- 1 sang jinieast 2083 Mar 21 23:44 AdminServer-attr-dl.jar -rw-rw---- 1 sang jinieast 4953 Mar 21 23:44 AdminServer-srvc-dl.jar -rw-rw---- 1 sang jinieast 13560 Mar 21 23:44 AdminServer.jar [daydreamer:229] !226 javap -classpath AdminServer-srvc-dl.jar examples/admin/AdminServerImpl_Stub Error: No binary file 'Administrable' [daydreamer:229] javap -classpath AdminServer-srvc-dl.jar:jini-ext.jar examples/admin/AdminServerImpl_Stub Error: No binary file 'DestroyAdmin' [daydreamer:229] javap -classpath AdminServer-srvc-dl.jar:jini-ext.jar:sun-util.jar examples/admin/AdminServerImpl_Stub Error: No binary file 'OurOwnAdmin'
61
Review Points
RMI codebase
Used
Set
62
ClassLoader Delegation
ClassLoader Delegation
Ask
Reason why a class file in local CLASSPATH gets picked up first before the same class file gets downloaded from remote location 64
Classloader Hierarchy
Application Classloader
CLASSPATH
RMI Classloader
RMI codebase
65
Example
RMI Client
Local Classpath
Interface1 Interface1
RMI Server
RMI Classloader
Interface1Impl_Stub
Interface2
Interface2Impl_Stub
66
RMI Security
Java Security
All code signed by Dave can write to a particular directory Any code downloaded from a particular HTTP server site has no filesystem access
68
69
70
RMI/Jini Security
Security is a serious concern since executable code is being downloaded from remote location In RMI/Jini, SecurityManager has to be installed in order to be able to download any code from remote location
Without
its installation, RMI/Jini will search for class files only from local classpath
RMI Security
RMI client needs to install security manager because it needs to download Stub file of RMI object A simple RMI server might not need to install security manager if it does not need to download class files from remote location
It
72
S1: Define remote interface S2: Implement remote interface S3: Provide an implementation for each remote method S4: Write server class
Contains
main() method Create and export remote object Create and install a security manager Register remote object with RMI registry
74
Defines methods that are called remotely Must be declared as public Extends the java.rmi.Remote interface Each method must declare java.rmi.RemoteException The data type of any remote object that is passed as an argument or return value (either directly or embedded within a local object) must be declared as the Remote interface type (for example, Hello) not the implementation class (HelloImpl).
75
Implement the remote interface Extend one of the two remote classes
java.rmi.server.UnicastRemoteObject java.rmi.activation.Activatable
By extending one of the two remote classes above, they are automatically exported
Throw RemoteException Install Security Manager Register remote objects with RMI registry
77
78
79
80
81
S3: Example
// Implement remote method public int getNextNumber(int n) { return n+1; }
82
83
S3: Example
// W rite main method public static void main(String[] args) { try { NextNumberImpl server = new NextNumberImpl(); } catch (RemoteException ex) { ex.printStackTrace(); } }
84
85
mechanism Typically is used by caller to get the remote reference of the first remote object
Client gets reference to remote object - actually reference to stub object of the remote object
86
registry returns the Stub instance of the remote object bound to that name
88
Example
// A client to test the NextNumber server package corejini.appendixa; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.rmi.NotBoundException; import java.rmi.Naming; import java.net.MalformedURLException; public class NextNumberClient { public static void main(String[] args) { if (args.length != 1) { System.err.println("Usage: NextNumberClient <url>"); System.exit(1); }
89
Example - Continued
if (System.getSecurityManager() == null) { System.setSecurityManager( new RMISecurityManager()); }
90
Example - Continued
Remote r = null; try { r = Naming.lookup(args[0]); } catch (RemoteException ex) { System.err.println("Couldn't contact registry."); System.exit(1); } catch (NotBoundException ex) { System.err.println("There is no object bound to " + args[0]); System.exit(1); } catch (MalformedURLException ex) { System.err.println("The string " + args[0] + " is not a valid RMI URL"); System.exit(1); }
91
Example - Continued
try { if (r instanceof NextNumber) { NextNumber nn = (NextNumber) r; System.out.println("Next number after 1 is " + nn.getNextNumber(1)); System.out.println("Next number after 2 is " + nn.getNextNumber(2)); } else { System.err.println("Uh oh, the name " + args[0] + "isn't a NextNumber"); } } catch (RemoteException ex) { ex.printStackTrace(); }
92
Build Process
Compile
Compile
rmic corejini.appendixa.NextNumberImpl
94
Example: RMIC
C:\files\corejini\appendixa>rmic corejini.appendixa.NextNumberImpl error: Class corejini.appendixa.NextNumberImpl not found. C:\files\corejini\appendixa>cd \files C:\files>rmic corejini.appendixa.NextNumberImpl C:\files>cd corejini\appendixa C:\files\corejini\appendixa>dir HELLOW~1 JAV NEXTNU~1 JAV NEXTNU~2 JAV NEXTNU~3 JAV NEXTNU~1 CLA NEXTNU~2 CLA NEXTNU~3 CLA NEXTNU~4 CLA NEXTNU~5 CLA 5,260 01-04-01 1:36p HelloWorldServiceActivatable.java 249 01-04-01 1:36p NextNumber.java 1,802 01-04-01 1:36p NextNumberClient.java 1,540 01-04-01 1:36p NextNumberImpl.java 227 06-21-01 10:56p NextNumber.class 1,719 06-21-01 10:56p NextNumberImpl.class 2,023 06-21-01 10:56p NextNumberClient.class 3,218 06-21-01 10:59p NextNumberImpl_Stub.class 1,640 06-21-01 10:59p NextNumberImpl_Skel.class
95
96
97
c:>java -jar C:\files\jini1_2\lib\tools.jar -port 8082 -dir c:\files\ -verbose In this example, no need for this since client is not exporting any classes
c:>cd \files c:\files>java -Djava.security.policy=c:\files\jini1_2\policy\policy.all corejini.appendixa.NextNumberClient rmi://hannah/nextNumber
98
Activation
Activation
Service could be shut down inadvertently or intentionally Activatable service gets restarted automatically when system boots up or on-demand basis
Persistently stores all activatable objects Default is <Directory where RMID gets started>/log directory They are run as child processes of RMID
Activatable services
100
(5) Client, via lookup operation, retrieves the proxy object, which contains the RMI reference (6) Client Stub talks to the service directly and gets an exception since the service (as an RMI server) is inactive (7) Client Stub then talks to RMID (9) Client now can talk directly with the service
101
(5) Client, via lookup operation, retrieves the proxy object, which contains the RMI reference (6) Client talks to the service directly .
102
RMID
As long as RMID is running and RMID log file is persistent, a service can get started on as needed basis Methods of destroying a service
Kill
Reggie (Lookup service) Mahalo (Transaction Manager) Outrigger (JavaSpace) Fiddler (Lookup Discovery Service) Norm (Lease Renewal Service) Mercury (Event Mailbox Service)
104
Activation Trouble-shooting
Possibly DNS lookup problem Try CTRL-\ (Solaris) and CTRL-BREAK (W in32) for stack trace -J-Dsun.rmi.server.activation.debugExec=true
For any RMI properties you want to set for activatable services (child processes of RMID), start RMID with -C-Dproperty=value
-C-Djava.rmi.server.logCalls=true
105
RMI Tunneling
RMI Tunneling
Features
Protocol runs over HTTP protocol Allows RMI client within a firewall to talk to an RMI server outside of the firewall RMI server cannot talk back to the RMI client No multicast discovery Have to use Unicast No event notification from RMI server to RMI client 107
Limitation
Implications to Jini
Review Points
client server
109
Remote Communication
registry
RMI RMI
client
RMI
server
110
Loading Classes
registry
RMI RMI
client
RMI
server
URL protocol
URL protocol
URL protocol
web server
web server
111
Method Invocation
callers VM stub reference dispatcher RMI runtime RMI runtime remote objects VM remote object
112
in RMI specification
Code
interface definitions
APIs and Semantics of those APIs Lookup service, Transaction, Remote events, Leasing
RMI-like
semantics
RMI Limitation
where the server is how to reach the server what the server can do
If
116
Client does not need to know where a particular service is located Client should not fail if the service is unavailable or becomes unavailable during execution Client and servers should be proactive in detecting failure conditions
117
Summary
RMI is for invoking methods of remote Java object Enables the movement of data and code
Data
(State of object) movement via serialized object Code movement via class downloading
118