Java RMI
Java RMI
dbc@csit.fsu.edu
dbc@csit.fsu.edu
Example
obj
res = obj.meth(arg) ;
Local Machine
Remote Machine
dbc@csit.fsu.edu
dbc@csit.fsu.edu
dbc@csit.fsu.edu
Sockets
Traditionally quite hard to program, although the java.net package
makes it relatively easy to establish a socket network connection to
another host. Communication takes place via streams, but you must
define the detailed protocols for message exchange yourself.
High-level compared with Unix sockets, but low-level compared to
RMI.
CORBA
See next semesters course. . .
dbc@csit.fsu.edu
References
Core
dbc@csit.fsu.edu
Getting Started
dbc@csit.fsu.edu
dbc@csit.fsu.edu
A Simple Example
dbc@csit.fsu.edu
10
java.rmi.Remote
dbc@csit.fsu.edu
11
java.rmi.RemoteException
dbc@csit.fsu.edu
12
dbc@csit.fsu.edu
13
dbc@csit.fsu.edu
14
Remarks
dbc@csit.fsu.edu
15
dbc@csit.fsu.edu
16
We have completed the Java files for the remote object class
itself, but we still need the actual client and server programs
that use this class.
In general there are some pieces of administrivia one has to
deal withpublishing class files and installing security
managers.
To minimize distractions, we initially make the simplifying
assumption that both client and server have copies of all class
files for MessageWriter (e.g., they may share access through
shared NFS directories).
Then we also dont need a security manager, because all code
is local, and therefore trusted.
dbc@csit.fsu.edu
17
A Server Program
dbc@csit.fsu.edu
18
Remarks
19
A Client Program
dbc@csit.fsu.edu
20
Remarks
dbc@csit.fsu.edu
21
Then. . .
dbc@csit.fsu.edu
22
Running HelloClient/HelloServer
dbc@csit.fsu.edu
23
Running HelloClient/HelloServer
dbc@csit.fsu.edu
24
Running HelloClient/HelloServer
dbc@csit.fsu.edu
25
Running HelloClient/HelloServer
dbc@csit.fsu.edu
26
Running HelloClient/HelloServer
dbc@csit.fsu.edu
27
dbc@csit.fsu.edu
28
dbc@csit.fsu.edu
29
30
dbc@csit.fsu.edu
31
32
dbc@csit.fsu.edu
33
Stubs
dbc@csit.fsu.edu
34
Stubs.
Each remote object class has an associated stub class, which
implements the same remote interfaces. An instance of the stub class
is needed on each client. Client-side remote invocations are actually
local invocations on the stub class.
Serialization.
Arguments and results have to be marshaledconverted to a
representation that can be sent over the Net. In general this is a highly
non-trivial transformation for Java objects. Serialization is also used
for distributing stubs.
dbc@csit.fsu.edu
35
Architecture
Internet
Client
Client
Code
Send marshaled
arguments
Stub
Return value
or throw exception
Server
Send marshaled
result or
exception
RMI
Run-time
System
dbc@csit.fsu.edu
Remote
Object
Return value
or throw exception
36
dbc@csit.fsu.edu
37
38
39
40
Marshalling of Arguments
41
Object Serialization
dbc@csit.fsu.edu
42
I/O Streams
43
Object Streams
etc, and:
public Object readObject() throws IOException, . . . {. . .}
dbc@csit.fsu.edu
44
dbc@csit.fsu.edu
45
46
c
d
a
b
c
e
47
b
d
a
c
b
e
48
dbc@csit.fsu.edu
49
dbc@csit.fsu.edu
50
51
dbc@csit.fsu.edu
52
dbc@csit.fsu.edu
53
dbc@csit.fsu.edu
54
55
dbc@csit.fsu.edu
56
dbc@csit.fsu.edu
57
Compiling
On the server:
rmic FileSourceImpl
javac FileServer
(Note rmic will automatically invoke javac if FileSourceImpl.java
has not previous been compiled. javac, in turn, will notice a
dependency on FileSource.java, and compile that file if necessary.)
On the client:
javac FileClient
dbc@csit.fsu.edu
58
Running FileClient/FileServer
dbc@csit.fsu.edu
59
Running FileClient/FileServer
dbc@csit.fsu.edu
60
Remarks
dbc@csit.fsu.edu
61
dbc@csit.fsu.edu
62
Client
Server
Request
Reference
Client
Code
Registry Store
Reference
Remote
Object
dbc@csit.fsu.edu
63
dbc@csit.fsu.edu
64
dbc@csit.fsu.edu
65
66
67
Summary
dbc@csit.fsu.edu
68
dbc@csit.fsu.edu
69
dbc@csit.fsu.edu
70
The Java serialization process stores all data fields from the
original object.
It does not store any representation of the code associated
with the methods in the objects class.
When an object is deserialized (e.g. on some client), the client
JVM must have some way of loading a class file that does
contain this information.
If it cannot find a suitable class file, the deserialization
process will fail. You will see a
java.rmi.UnmarshalException thrown, with a nested
java.lang.ClassNotFoundException.
When you are doing development using RMI, you will
probably see this exception a lot!
dbc@csit.fsu.edu
71
In RMI, there are at least two ways to get the class files to the
client.
The straightforward approach is to manually copy class files
for all stub classes to the client: either put them in the current
directory on the client, or in some directory on the clients
CLASSPATH.
This approach is reliable, easy to understand, and perhaps the
best approach for initial experiments with RMI.
Eventually you may find it is too limiting. One of the benefits
of the OO approach is supposed to be that the user code (here
the client) doesnt need need to know the exact
implementation class in advanceonly the interface. But
stubs are associated with the implementation class.
dbc@csit.fsu.edu
72
dbc@csit.fsu.edu
73
Client
JVM
Server
Client
Request stub
class file
Web
Server
html/
download/
MyImpl_Stub.class
dbc@csit.fsu.edu
Server
(myWWW)
74
Remarks
dbc@csit.fsu.edu
75
dbc@csit.fsu.edu
76
Properties
77
dbc@csit.fsu.edu
78
dbc@csit.fsu.edu
79
If the loaded class uses further classes, not already loaded into
the JVM:
If the used class can be found on the local CLASSPATH, it is loaded
from there.
Otherwise, the class is loaded dynamically from the same URL as the
first class.
dbc@csit.fsu.edu
80
Security Managers
dbc@csit.fsu.edu
81
This isnt the end of the story. You also have to define a new
property: the java.security.policy property.
In simple cases this property is needed for clients, whereas
java.rmi.server.codebase is needed for servers.
dbc@csit.fsu.edu
82
The simplest security policy you can define is a plain text file with
contents:
grant {
permission java.security.AllPermission , ;
};
For now you can use this policy, but please avoid dynamically
loading code you cannot trust!
dbc@csit.fsu.edu
83
dbc@csit.fsu.edu
84
This also works for any classes (not just stubs) whose serialized
form may be communicated via remote method calls. You just
need to reinterpret server and client application according to
the direction the serialized object movesas source and
destination application.
In practice. . .
dbc@csit.fsu.edu
85
dbc@csit.fsu.edu
86
dbc@csit.fsu.edu
87
dbc@csit.fsu.edu
88
89
90
dbc@csit.fsu.edu
91
dbc@csit.fsu.edu
92
Remarks
The most crucial change is that the server now sets the
java.rmi.server.codebase property.
In this simplified example the Web Server URL is hardwired into the code.
In production quality code, a better strategy may be to first
check (e.g. using getProperty()) whether a property is
defined on the command-line, and, if not, read it from some
properties file.
Here the port number on which the registry listens is taken
from the first command-line argument. A registry is started
internally.
dbc@csit.fsu.edu
93
A Client Program
dbc@csit.fsu.edu
94
Remarks
dbc@csit.fsu.edu
95
Deployment
On the server:
rmic MessageWriterImpl
javac HelloServer
dbc@csit.fsu.edu
96
Running FileClient/FileServer
dbc@csit.fsu.edu
97
Running FileClient/FileServer
dbc@csit.fsu.edu
98
Running FileClient/FileServer
dbc@csit.fsu.edu
99
Running FileClient/FileServer
dbc@csit.fsu.edu
100
Remarks
dbc@csit.fsu.edu
101
Applets
dbc@csit.fsu.edu
102
Applets
dbc@csit.fsu.edu
103
Applets Today
104
105
dbc@csit.fsu.edu
106
dbc@csit.fsu.edu
107
Driving code for a trivial Swing application that reads entries from
a file and displays them in a list:
import java.util.* ;
import java.io.* ;
import java.awt.event.* ;
import javax.swing.* ;
. . . declaration of classes FilePanel and FileFrame . . .
public class FileDisplayTest {
public static void main(String [] args) {
FileDisplay frame = new FileDisplay() ;
frame.addWindowListener(new TerminationListener()) ;
frame.setVisible(true) ;
}
}
. . . declaration of class TerminationListener . . .
dbc@csit.fsu.edu
108
dbc@csit.fsu.edu
109
dbc@csit.fsu.edu
110
Conversion to an Applet
dbc@csit.fsu.edu
111
dbc@csit.fsu.edu
112
on the host:
sirah.csit.fsu.edu
113
114
115
dbc@csit.fsu.edu
116
To view this applet, you will need a browser with the Java
plug-in installed.
If you have a suitable PC where you can install this software,
go to:
http://javasoft.com/products/plugin/
and follow the link for JRE 1.3 for Microsoft Windows.
Download the executable file into a suitable directory on your
PC, and run it.
The plug-in is now installed.
If you are unable to install the plug-in, but have a suitable Java 2 JDK
installation, you can view the applet using the appletviewer command
instead. Pass the URL on the command line.
dbc@csit.fsu.edu
117
dbc@csit.fsu.edu
118
What we really want is for the Applet to read file entries from
a file on the server.
In fact this limited objective could be achieved with an HTTP
GET request, but a more general approach is to use RMI.
dbc@csit.fsu.edu
119
120
An Updated Client
121
View the applet with the browser while the server program is
running.
dbc@csit.fsu.edu
122
123
ps udbc
TTY
TIME CMD
?
00:00:00 java
pts/2
00:00:00 bash
kill -9 30399
# The process ID
dbc@csit.fsu.edu
124
dbc@csit.fsu.edu
125
Applets are not a primary focus of these lectures, but we briefly review
some of their other properties.
In the FileDisplay example, the GUI was created in the constructor of the
applet.
This is slightly unusual for an applet. It is more traditional to do
initialization in a method called init()one of several applet eventhandling methods:
init()
start()
stop()
destroy()
126
127
Applet Parameters
128
An Improved Applet
This version will read the port number (and file name) from
the applet parameters:
public class FileDisplay extends JApplet {
FileSource server ;
FilePanel panel = new FilePanel() ;
public void init() {
try {
getContentPane().add(panel) ;
server = (FileSource)
Naming.lookup(rmi://sirah.csit.fsu.edu: +
getParameter(port) +
/fileservice) ;
} catch(Exception e) { . . . }
}
...
}
dbc@csit.fsu.edu
129
An Improved Applet
dbc@csit.fsu.edu
130
stop()
If you are writing a more general applet that allows the file to
be updated, overriding the stop() method might be one natural
place to save locally cached data back to the server.
dbc@csit.fsu.edu
131
dbc@csit.fsu.edu
132
dbc@csit.fsu.edu
133
dbc@csit.fsu.edu
134
A Generic Service
All the client knows in advance are the two simple interfaces
GenericService and GUI. The code for the actual service
and GUI are downloaded dynamically. The GUI might be an
arbitrary Swing interface.
dbc@csit.fsu.edu
135
Example: Jini
dbc@csit.fsu.edu
136
Example: Call-backs
dbc@csit.fsu.edu
137
138
dbc@csit.fsu.edu
139
Remote Object
(Chatter_Impl)
notify(m)
Server
notify(m)
notify(m)
Client
Remote Object
(Chatter_Impl)
Client
dbc@csit.fsu.edu
Remote Object
(Chatter_Impl)
Client
140
141
142
Synchronization
Where multiple clients may interact with the same object (this
means most useful services), one needs to pay attention to
issues of interference.
Remote invocations from different clients may execute
concurrentlyin different threadsin the server programs
JVM.
It can be a good idea to declare the implementation of remote
methods (in the definition of the implementation class) with
the synchronized modifier.
This avoids the dangerous situation in which methods are
being invoked simultaneously on a remote object by several
clients.
Other clients will have to wait until the currently executing method has
completedthey will be serviced in turn.
But now you must be wary of possible deadlocks.
dbc@csit.fsu.edu
143
dbc@csit.fsu.edu
144
Garbage Collection
145