George Blank
George Blank
University Lecturer
J
J
ava RMI
ava RMI
Introduction to RMI
Introduction to RMI
J
J
ava RMI
ava RMI
Introduction to RMI
Introduction to RMI
J
J
ava and the Web
ava and the Web
J
J
ava¶s popularity is due to its suitability for use
ava¶s popularity is due to its suitability for use
on the World Wide Web (WWW).
on the World Wide Web (WWW).
Se
Seve
vera
ral Web
l Web br
brow
owse
sers h
rs hav
ave su
e supp
ppor
ort fo
t for
r
JJava:
ava:
±
± NeNetstscacape Npe Navavigigatator or ±
± InInteternrnet et ExExplplororer er ±
± HHoottJJavaava
J
J
ava incorporates audio, video, and animation
ava incorporates audio, video, and animation
directly on the web page.
directly on the web page.
Method Modifiers
Instance Methods
Class Methods
Abstract Methods
Native Methods
Final Methods
Method Modifiers with Effect on
Scoping
public
: Method can be accessed by any class
private
: methods accessed only by class
methods
friendly
: methods accessed by other methods in
the same package
protected
: methods accessed by subclass
Interfaces
A
Java interface is similar to a class, except
there is no data associated with the interface.
Example:
public interface MyInterface {
methods-with no implementation details
final variables
P
roperties of Interfaces
The variables in an interface must be final.
The methods are only declarations.
A class that extends another class is
guaranteed to support the contracts entered
into by its superclass.
Interfaces are used to approximate multiple
inheritances
J
ava Native Interface (
J
NI)
The Java Native Interface (JNI) is part of the core JDK and provides a framework for
interfacing to native code. The native code is not easily portable across different hardware platforms. So using native code takes way one of the major advantages of java. JNI was
developed to bridge the gap.
When to use
J
NI
When the standard Java class library does not support the platform-dependent features
needed by the application.
You need to use a library written in another language, and wish to make it accessible to Java code through the JNI.
You want to implement a small portion of time-critical code in a lower-level language such as assembly.
J
NI Capabilities
You can use native methods to:
± Create, inspect, and update Java objects (including arrays and strings).
± Call Java methods.
± Catch and throw exceptions.
± Load classes and obtain class information. ± Perform runtime type checking.
Enabling
J
ava code with
J
NI
You can use the JNI with the Invocation
API to enable an arbitrary native
application to embed the Java VM.
Programmers can make their existing
applications Java-enabled without
Remote Method Invocation
RMI provides the means to invoke methods
remotely.
RMI allows for applications to communicate and
execute across multiple systems on a network.
RMI is supported by the java.rmi, java.rmi.server,
and java.rmi.registry
Enhanced security of
Java 2 requires a security
P
arts in a RMI System
Interface definitions for remote services
Implementations of the remote services
Stub and Skeleton files
A server to host the remote services
An RMI Naming service that allows clients to find
the remote services
RMI process
Java Client Java Server
Client Stub Server Skeleton
Client Method Called Method
Network transport Network Transport arguments results
Network
Not needed In Java 2
RMI Server, Client, and Registry
The server process registers the remote
object X with the registry using the
N
aming.bind()
method.
The client calls
Naming.lookup()
, which
contacts the registry and obtains a stub object
for X.
The client then uses the stub as if it is a local
object.
Stub Class
A stub for a remote object is the
client-side proxy for the remote object. Such
a stub implements all the interfaces
that are supported by the remote object
implementation. The client-side stub
responsibilities are shown on the next
slide.
Stub Class Responsibilities
Initiating a call to the remote object (by calling the remote reference layer).
Marshaling arguments to a marshal stream (obtained from the remote reference layer).
Informing the remote reference layer that the call should be invoked.
Unmarshaling the return value or exception from a marshal stream.
Informing the remote reference layer that the call is complete
.
Skeleton Class
A skeleton for a remote object is a server-side entity that contains a method which dispatches calls to the actual remote object implementation. The skeleton is responsible for:
± Unmarshaling arguments from the marshal stream. ± Making the up-call to the actual remote object
implementation.
± Marshaling the return value of the call or an exception (if one occurred) onto the marshal stream.
Remote Reference Layer
The remote reference layer deals with the lower level transport interface and is
responsible for carrying out a specific remote reference protocol which is independent of the client stubs and server skeletons. The remote reference layer has two cooperating
components: the client-side and the server-side components.
Remote Reference Layer (2)
The client-side component contains
information specific to the remote server (or servers, if the remote reference is to a
replicated object) and communicates via the transport to the server-side component.
During each method invocation, the client and server-side components perform the specific remote reference semantics.
Remote Reference Layer (3)
For example, if a remote object is part of a replicated object, the client-side component can forward the invocation to each replica rather than just a single remote object.
In a corresponding manner, the server-side component implements the specific remote reference semantics prior to delivering a remote method invocation to the skeleton.
Remote Reference Layer (4)
For example, the server side could handle ensuring atomic multiple delivery by communicating with other servers in the replica group.The remote
reference layer transmits data to the transport layer via the abstraction of a stream-oriented connection. The transport takes care of the implementation
details of connections. Although connections present a streams-based interface, a connectionless
transport may be implemented beneath the abstraction
RMI Registry
The Registry tracks the addresses of the
remote objects exported by applications
It is the central management point for RMI
Does not actually invoke remote methods
Bind() links the object in the registry
P
arameter
P
assing
When a remote procedure is executed, the
java.rmi runtime encodes the arguments and
sends them over the network to a server that
decodes them.
The server then invokes the method, encodes
the results, and sends it back.
Finally, the client-side java.rmi runtime
decodes the result.
P
arameter Marshalling
RMI stubs are responsible for packaging
parameters used in a remote method in a
block of bytes using the big-endian byte
order. This is called parameter marshalling.
A receiver object on the server must
Building RMI Applications
Define remote interfaces
Create classes that implement the interfaces
Create stub and skeleton classes for the
implementation classes.
Create Security
Policy
A Distributed
Hello World
P
rogram
Using RMI
It uses an applet to make a remote method
call to the server from which it was
downloaded to retrieve the message "Hello
World!".
When the applet runs, ³Hello World!´ is
displayed on the client browser.
Steps Involved
Write The HTML and
Java Source Files.
Compile and Deploy Class Files and HTML
Files.
Start the Remote Object Registry, Server,
and Applet
Source Files
The Java remote interface. (Hello.java)
The Java remote object (server) which implements
the remote interface. (HelloImpl.java)
The Java applet that remotely invokes the remote
method, sayHello(). (HelloApplet.java)
The HTML code for the web page that references the applet. (hello.html)
The Remote Interface
Must be public.
Extends the interface java.rmi.Remote.
Each method must declare
java.rmi.RemoteException in its throws
clause
A remote object passed as an argument or
return value must be declared as the remote
interface.
package examples.hello; import java.rmi.Remote;
import java.rmi.RemoteException; public interface Hello extends
java.rmi.Remote {
String sayHello() throws java.rmi.RemoteException; }
The Implementation Class
Specify the remote interface(s) being
implemented.
Define the constructor for the remote object.
P
rovide implementations for the methods that
can be invoked remotely.
The Implementation Class
(Cont¶d)
Create one or more instances of a remote
object.
Register at least one of the remote objects
with the RMI remote object registry, for
bootstrapping purposes.
Server Code (1)
package examples.hello; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.rmi.server.UnicastRemoteObject;public class HelloImpl extends UnicastRemoteObject implements Hello {
public HelloImpl() throws RemoteException { super();
// Implementation of remote method public String sayHello() {
return "Hello World!"; }
public static void main(String args[]) { // Create and install a security manager if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
HelloImpl obj = new HelloImpl();
// Bind this object instance to the name "HelloServer" Naming.rebind("//afsxx.njit.edu/HelloServer", obj);
System.out.println("HelloServer bound in registry"); }
catch (Exception e) {
System.out.println("HelloImpl err: " + e.getMessage()); e.printStackTrace();
} } }
Notes on Server Code
By extending remote class UnicastRemoteObject, the HelloImpl class can be used to create a remote object that:
± Uses RMI's default sockets-based transport for communication
± Runs all the time (In Java 2 SDK, the object can be activated
(created) when a client requests it, using Remote Object Activation, rather than running all the time ± extend
java.rmi.activation.Activatable )
To bind to a different port, for example 2001, use:
Notes on Server Code (contd)
Arguments to, or return values from, remote methods can be
any data type for the Java platform, including objects, as long as
those objects implement the interface java.io.Serializable.
By default, local objects are passed by copy, which means that all data members (or fields) of an object are copied, except those marked as static or transient
Remote objects are passed by reference. A reference to a
remote object is actually a reference to a stub, which is a client-side proxy for the remote object.
Notes on Server Code (contd)
Security manager guarantees that the classes that get loaded perform only allowed operations.
If no security manager is specified, no class loading, by RMI clients or servers, is allowed, aside from what can be found in the local CLASSP ATH.
Client Applets use the security manager already installed in the client browser .
If the client were an application rather than an applet, Security manager would need to be installed.
A security manager is required in any JVM that needs to
download code, and RMI clients need to download RMI stubs (as well as any other custom classes or interfaces needed to communicate with the RMI server).
A Remote Service Applet
package examples.hello; import java.applet.Applet; import java.awt.Graphics; import java.rmi.Naming; import java.rmi.RemoteException;public class HelloApplet extends Applet { String message = "";
// "obj" is the identifier that we'll use // to refer to the remote object that
// implements the "Hello" interface Hello obj = null;
public void init() { try {
Hello obj = (Hello)Naming.lookup("//" + getCodeBase().getHost() + "/HelloServer"); message = obj.sayHello(); } catch (Exception e) { System.out.println("Applet exception: " + e.getMessage()); e.printStackTrace(); } }
public void paint(Graphics g) {
g.drawString(message, 25, 50); }
}
Notes on Client Applet
The applet gets a reference to the remote object implementation (advertised as "HelloServer") from the server host's rmiregistry.
The applet invokes the remote sayHello method on the server's remote object.
The applet invokes the paint method, causing the string "Hello World!" to be displayed in the drawing area of the applet.
The Web
P
age (hello.html)
<
HTML>
<
title>Hello World
</title>
<
center>
<h1>Hello World
</h1>
</center>
<
p>
<
applet codebase="
myclasses/"
code="examples.hello.HelloApplet"
width=500 height=120>
</
applet>
</HTML>
Compiling the
J
ava Source Code
Create a directory myclasses in your
public_html on AFS and compile the java
code:
javac -d $HOME/public_html/myclasses
Generate Stubs and Skeletons
rmic -d $HOME/public_html/myclasses examples.hello.HelloImpl The following files are created in the directory:
$HOME/public_html/myclasses/examples/hello HelloImpl_Stub.class
J
ava 2 SDK Stubs
In the Java 2 SDK implementation of RMI, skeleton classes are
obsolete. RMI uses reflection to make the connection to the remote service object.
If you will never need support for 1.1 clients, rmic can be run with the -v1.2 option
rmic ±v1.2 -d $HOME/public_html/myclasses examples.hello.HelloImpl
This creates only
Deploying Applet (1)
Move the HTML File (hello.html) to the Deployment
Directory:
Sample
P
olicy File for User
(.java.policy) in $HOME
grant {
permission java.net.Socket
Permission
"*:1024-65535","connect,accept";
permission java.net.Socket
Permission "*:80",
"connect";
};
Replace * with name or I
Pof client to restrict
Security
P
olicy
In a Unix environment, you will probably need
to create a Security
Policy for the Client
Application but not for an applet. The default
policy might work in Windows.
To create a security policy, see a
Java text
book.
Just Java 2, pages 351-368, gives an
explanation. Some students have expressed
a preference for the explanation in
Core Java 2.
Start the Remote Object Registry
The RMI registry is a simple server-side bootstrap name server that allows remote clients to get a reference to a remote object.
Start registry on server - UNIX: rmiregistry &
Windows:
start rmiregistry
To start on a port other than the default 1099, for example port 2001:
Starting the Server
java
-Djava.rmi.server.codebase=http://afsxx.njit.edu/~username/myclasses /
-Djava.security.policy=$HOME/.java.policy examples.hello.HelloImpl The output should look like this:
Starting the Server
When starting the server, the java.rmi.server.codebase property must be specified, so that the stub class can be dynamically downloaded to the registry and then to the client.
Run the server, setting the codebase property to be the location of the implementation stubs. Because the
codebase property in this example references a directory, make sure that any other classes that may need to be
downloaded have also been installed in the directory referenced by java.rmi.server.codebase
Starting the Server
Note: A stub class is dynamically downloaded to a client's virtual machine only when the class is not already available locally and the
java.rmi.server.codebase property has been set properly to specify where the class files are located
on the server.
You can also specify the java.security.policy property for the server to set permissions.
Common Exception
If you forget the trailing slash on the codebase
property, or if the class files can't be located at the source (they aren't really being made available for download) or if you misspell the property name, you'll get thrown a java.lang.ClassNotFoundException. You will also need to use a VPN if you access the
RMI server from off-campus because AFS security does not allow remote connections from unsigned applets. Otherwise you will get a
Running the Applet
appletviewer
http://afsxx.njit.edu/~usrname/hello.html &
Or use the Browser URL:
http://afsxx.njit.edu/~usrname/hello.html
String H ello World should display.
Note: The Applet sandbox allows them to connect only to
their host URL. Therefore, the AFS hostname should be of the AFS machine on which the RMI server is running.
Output
Browser
Note: Use web.njit.edu, not afs xx as shown. That will not work as Web server access to AFS is now disabled.
Advantages of RMI
Object-Oriented
Safe and Secure
Easy to Write/Easy to Use
Connects to Existing/Legacy Systems (
JNI)
Write Once, Run Anywhere
Distributed Garbage Collection
Garbage Collection
The Java Virtual Machine has an automatic
garbage collector that will reclaim the memory from any object that has been discarded by the running program. Garbage collection is difficult if the server and client run on different machines. The RMI subsystem implements a reference
counting-based distributed garbage collection (DGC) algorithm to provide automatic memory management facilities for remote server objects.
How DGC works
The remote server keeps track of all external client references. When a reference is made, the server increases the object reference count by one and
marks the object as "dirty". When a client drops the reference, the DGC decreases its reference count by one and marks the object as "clean." When the
reference count reaches zero, the remote object is free of any live client references. It is then placed on the weak reference list and subject to periodic garbage collection.
RMI Limitations
RMI is not full featured middleware
No mechanism for object description
No server events
J
ava only, not language independent
Firewalls are not supported
Naming service is not persistent
No load balancing
Example
Example
Use
Users
rs fil
fill in
l in th
the f
e fiel
ields o
ds of a
f an ex
n expe
pense r
nse rep
eport
ort..
Clients communicate with the server
Clients communicate with the server using
using
RMI. The server stores the expense reports in
RMI. The server stores the expense reports in
a database using
Remote Interface
Remote Interface
import java.rmi.*;
import java.rmi.*;
public interface ExpenseServer extends Remote {
public interface ExpenseServer extends Remote {
P
P
olicy get
olicy get
PPolicy() throws RemoteException;
olicy() throws RemoteException;
void
void submitReport(Exp
submitReport(ExpenseReport report)
enseReport report)
throws RemoteException,
throws RemoteException,
InvalidReportException;
InvalidReportException;
}}
The
The
P
P
olicy Interface
olicy Interface
public interface
public interface
PPolicy {
olicy {
void check
void check
VValid(ExpenseEntry entry)
alid(ExpenseEntry entry)
throws
throws
PPolicy
olicy
VViolationException;
iolationException;
Client Code
Policy cur Policy = server.getPolicy();
while (user keeps adding entries) { try {
cur Policy.checkValid(entry); // throws exception if not OK
add the entry to the expense report } catch (PolicyViolationException e) {
show the error to the user } }
Server Code (1)
import java.rmi.*;
import java.rmi.server.*;
class ExpenseServerImpl extends UnicastRemoteObject implements ExpenseServer
Server Code (2)
{
ExpenseServerImpl() throws RemoteException { // ...set up server state...
}
public Policy getPolicy() {
return new TodaysPolicy(); }
public void submitReport(ExpenseReport report) { // ...write the report into the db...
Implementing a
P
olicy
public class TodaysPolicy implements Policy {
public void checkValid(ExpenseEntry entry) throws PolicyViolationException
{
if (entry.dollars() < 20)
return; // no receipt required throw new PolicyViolationException(
"Need a receipt"); }
New
P
olicy Implementation
public class Tomorrows
Policy implements
Policy {
public void checkValid(ExpenseEntry entry)
throws
PolicyViolationException
{
if (entry.isMeal() && entry.dollars() < 20)
return;
// no receipt required
throw new
PolicyViolationException(
"Need a receipt");
}
Summary
J
ava RMI is a distributed object model for the
Java platform.
RMI extends the
Java object model beyond a
single virtual machine address space.
RMI uses object serialization to convert object
graphs to byte streams for transport.
Defining Interfaces
All methods that can be run remotely must be
declared as part of an interface that extends
R
emote
.
public interface RemOp extends Remote {
public void call() throws RemoteException;
}
Creating Classes that Implement
the Interfaces
Classes that implement the remote interfaces
must be subclasses of the
RemoteObject
class.
RemoteObject provides support for the
package rmi1;
import java.rmi.*;
import java.rmi.server.*;
public class RemImpl extends UnicastRemoteServer
implements RemoOp {
public static void main(String[] args) {
System.setSecurityManager(
new StubSecurityManager());
try {
Naming.rebind(³operator´, new RemImpl());
} catch (Exception x) {
x.printStackTrace(); return; } }
public RemImpl() throws RemoteException {
}
public void call() throws RemoteException {
System.out.println(getName());
System.out.println(³Location: ³ +
System.get
Property(³LOCATION´));
}
public String getName() {
return ³Remote operation: ³ + hashCode();
}
}
package rmi1;
import java.rmi.*;
import java.rmi.server.*;
public class OpTest {
public static void main(String[] args) {
System.setSecurityManager(
new StubSecurityManager()):
try {
RemOp ro = (RemOp) Naming.lookup(³operator´);
ro.call();
} catch (Exception x) { x.printStackTrace();
System.exit(-1); } } }
Running the rmi1 Example
java java.rmi.registry.RegistryImpl
java -DLOCATION=server rmi1.RemImpl
java -DLOCATION=client rmi1.OpTest
Output:
Remote operation: 841549921
Location: server
RMI Security
One of the most common problems encountered with RMI is a failure due to security constraints.
The security policy can be set by constructing a SecurityManager object and calling the
setSecurityManager method of the System class. The SecurityManager class has a large number of
methods whose name begins with check. For example, checkConnect (String host, int port).
Security Continued
If the current security policy does not allow connection to this host and port, then the call throws an exception. This usually causes the program to terminate with a message such as:
java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099
Java-RMI vs. CORBA and DCOM
Java-RMI
is a
Java-specific middleware spec that
allows client
Java programs to invoke server
Java
objects as if they were local.
J
ava-RMI is tightly coupled with the
Java
Comparison Continued
Since Java-RMI is tightly coupled with The Java
Language, Java-RMI can work with true sub-classes.
Because of this, parameters passed during method calls between machines can be true Java Objects. This is
Comparison Continued
If a process in an RMI system receives an object of a class that it has never seen before, it can request that its class information be sent over the network.
Over and above all this, Java-RMI supports
Distributed Garbage Collection that ties into the local Garbage Collectors in each JVM.
Trouble Shooting
Trouble Shooting
IIf f aa JVJVM that is exporting remote objects does not have theM that is exporting remote objects does not have the
java.rmi.server.codebase
java.rmi.server.codebase property set correctly, you will getproperty set correctly, you will get a class not found error.
a class not found error. Def
Defaulault pot port fort for RMr RMI ReI RegigistrstryIyImpmpl is 10l is 1099. I99. If it if it is als alreaready indy in use, you will get a
use, you will get a
java.net.SocketExce
java.net.SocketException: Address already in ption: Address already in use.use.
Do
Do not not try try to to use use the the looloopbapback adck addredress, ss, 12127.07.0.0..0.11 improperly.
improperly. It It does not does not work on work on a a network.network. RM
RMI I is is subsubjeject tct to Co Connonnectection ion ExcExcepteptionions ths that at areare
idiosyncratic and difficult to overcome. This is one of the idiosyncratic and difficult to overcome. This is one of the most common topics in RMI discussions.
P
P
roblems Encountered
roblems Encountered
A
A java.rmi.NotBoundException java.rmi.NotBoundException was overcome bywas overcome by
bypassing the start command and starting the server bypassing the start command and starting the server
directly. This is not recommended, as the program will not directly. This is not recommended, as the program will not exit normally
exit normally. . NOTE: A probable cause is another vNOTE: A probable cause is another versionersion of
of JJava on the system that is referenced by the startava on the system that is referenced by the start
command. command. S
Seevveerraall java.rmi.UnmarshallException java.rmi.UnmarshallException were caused bywere caused by classes not in the class path. Some s
classes not in the class path. Some students just had totudents just had to add the current directory:
add the current directory:
set classpath=.
P
P
roblems Encountered
roblems Encountered
An
An IncIncomompatpatiblible Tye Type Epe Excexceptiption eon errorror ocr occurcurred red whwhen aen a group failed to cast a returned
group failed to cast a returned reference to thereference to the <ClassName>_stub
<ClassName>_stub type.type. A ja
A java.va.secsecuriurityty.Ac.AccescessCosContrntrololExcExcepteption reqion requiuired crered creatiatingng a policy file and referencing it as
a policy file and referencing it as
java -Dj
java -Djava.security.policy=c:\rmi.polava.security.policy=c:\rmi.policyicy
<Y
<YourClient.ourClient./<Y/<YourServer> ourServer>
Don
Don¶t o¶t oververlolook stok standandard pard progrogramramminming errog errors lrs like ike synsyntaxtax errors, missing try blocks, and naming and typing
errors, missing try blocks, and naming and typing mistakes.
Hints
When you have a problem, you may have to kill all your processes and restart everything.
You must start the registry (Windows command) start rmiregistrystart
All remote interfaces must extend
java.rmi.RemoteInterface, and all remote objects must extend java.rmi.UnicastRemoteObject.
Security management and implementing class policies are complex and difficult in RMI. The client policy file
Lessons Learned
You can get a trace of the server activity using
java -Djava.rmi.server.logCalls=true <YourServer>
Properties beginning java.rmi.* are part of published RMI
spec and docs, while sun.rmi.* indicates things that may vary.
You can find the host name of a caller of a remote method with
java.rmi.server.RemoteServer.getClientHost
On a server with multiple host names, you need to force a fully qualified host name with
Environment Conflicts
If you may have multiple versions of Java on your
system, try java -version to see which version your environment defaults to. Remember that different
versions seldom work together, and that your Windows autoexec.bat file may set some environment values that you might not think about.
Good RMI explanation
The example from the Sun Web site is difficult
to get working, because it includes a lot of
material that goes beyond the basics. You
may wish to find a simpler example. One
excellent one was at
± http://www.ccs.neu.edu/home/kenb/com3337/rmi_tut.ht ml
RMI
V
ersions
Java 2 SDK, version 1.4 adds server-side stack trace
retention, Service Provider Interface for RMIClassLoader and Dynamic Server Host Name.
Java 2 SDK, version 1.3 adds enhancements to serialization Java 2 SDK, version 1.2 adds activation, the use of custom socket protocols and security policies.
Java 1.1 added core RMI support, but usually requires running applets in the applet viewer.
Java 1.0.2 was an interim release, and should not be used for RMI.