Download RMI

Document related concepts
no text concepts found
Transcript
George Blank
University Lecturer
RMI
Introduction to RMI
Warning
• This course is very volatile. Software is
upgraded every semester. You should not
assume that an example in the presentation is
complete, or that it will work in the present
environment. It is best to get your code
examples from the Sun Java tutorials and
modify them to work. Use the lectures to
understand the general principles.
Java and the Web
• Java’s popularity is due to its suitability for use
on the World Wide Web (WWW).
• Several Web browsers have support for Java:
– Netscape Navigator
– Internet Explorer
– HotJava
• Java incorporates audio, video, and animation
directly on the web page.
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
policy implementation.
Serializable objects
• For a parameter to be passed remotely in Java, it
must be serializable. This means that it must be
capable of being packaged in a form that can be
marshaled and unmarshaled. Marchaling is the
process of packaging information so that it can
be passed over a connection without errors due
to any differences in the client and server
environments.
Remote References
• A remote reference needs a network address and
endpoint f a server plus a local reference for the
actual object to be addressed, used only by the
server. The remote reference is built from two
classes, a server class on the server side and a client
class on the client side.
• See explanation in Tanenbaum and van Steen, page
97.
Parts 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
• A class file provider (an HTTP or FTP server)
RMI process
Java Client
Java Server
Client Method
Called Method
arguments
results
Client Stub
Server Skeleton
Not needed
In Java 2
Network transport
Network Transport
Network
RMI Server, Client, and Registry
• The server process registers the remote
object X with the registry using the
Naming.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 clientside 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 serverside 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
• Rebind() replaces object with a new one
Parameter Passing
• 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.
Parameter 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 unmarshall
the parameters or report errors.
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 Program
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.
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.
• Provide implementations for the methods that
can be invoked remotely.
• Create and install a security manager.
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();
}
Server Code (2)
// Implementation of remote method
public String sayHello() {
return "Hello World!";
}
Server Code (3) main begins
public static void main(String args[]) {
// Create and install a security manager
if (System.getSecurityManager() == null)
{
System.setSecurityManager(new RMISecurityManager());
}
Server Code (4) main ends
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:
Naming.rebind("//afsxx.njit.edu:2001/HelloServer", obj);
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 clientside 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 CLASSPATH.
• 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;
Remote Applet Code (2)
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();
}
}
Remote Applet Code (3)
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 Page (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 Java Source Code
• Create a directory myclasses in your
public_html on AFS and compile the java
code:
• javac -d $HOME/public_html/myclasses
Hello.java HelloImpl.java HelloApplet.java
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
HelloImpl_Skel.class (before Java 2 only)
Java 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
HelloImpl_Stub.class
Deploying Applet (1)
• Move the HTML File (hello.html) to the Deployment
Directory:
$HOME/public_html/
Sample Policy File for User
(.java.policy) in $HOME
grant {
permission java.net.SocketPermission
"*:1024-65535","connect,accept";
permission java.net.SocketPermission "*:80",
"connect";
};
Replace * with name or IP of client to restrict
access
Security Policy
• 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:
rmiregistry 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:
HelloServer bound in registry
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
Java.rmi.ConnectException
Running the Applet
appletviewer
http://afsxx.njit.edu/~usrname/hello.html &
Or use the Browser URL:
http://afsxx.njit.edu/~usrname/hello.html
String Hello 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
Appletviewer
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
Parallel Computing
RMI Limitations
•
•
•
•
•
•
•
RMI is not full featured middleware
No mechanism for object description
No server events
Java only, not language independent
Firewalls are not supported
Naming service is not persistent
No load balancing
Summary
• Java 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
Remote .
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
hashCode(), equals(), and toString().
Interface Class Example (1)
package rmi1;
import java.rmi.*;
import java.rmi.server.*;
Interface Class Example (2)
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; } }
Interface Class Example (3)
public RemImpl() throws RemoteException {
}
public void call() throws RemoteException {
System.out.println(getName());
System.out.println(“Location: “ +
System.getProperty(“LOCATION”));
}
Interface Class Example (4)
public String getName() {
return “Remote operation: “ + hashCode();
}
}
Interface Class Example (5)
package rmi1;
import java.rmi.*;
import java.rmi.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
connect,resolve)
Trouble Shooting
• If a JVM that is exporting remote objects does not have the
java.rmi.server.codebase property set correctly, you will get
a class not found error.
• Default port for RMI RegistryImpl is 1099. If it is already in
use, you will get a
java.net.SocketException: Address already in use.
• Do not try to use the loopback address, 127.0.0.1
improperly. It does not work on a network.
• RMI is subject to Connection Exceptions that are
idiosyncratic and difficult to overcome. This is one of the
most common topics in RMI discussions.
Problems Encountered
• A java.rmi.NotBoundException was overcome by
bypassing the start command and starting the server
directly. This is not recommended, as the program will not
exit normally. NOTE: A probable cause is another version
of Java on the system that is referenced by the start
command.
• Several java.rmi.UnmarshallException were caused by
classes not in the class path. Some students just had to
add the current directory:
set classpath=.’%classpath%
Problems Encountered
• An Incompatible Type Exception error occurred when a
group failed to cast a returned reference to the
<ClassName>_stub type.
• A java.security.AccessControlException required creating
a policy file and referencing it as
java -Djava.security.policy=c:\rmi.policy
<YourClient./<YourServer>
• Don’t overlook standard programming errors like syntax
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
permits connection to a specific referenced port number.
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
java.rmi.server.useLocalHostname=true
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 Versions
• 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.
References
• Andrew Tanenbaum and Martin van Steen, Distributed
Systems, Prentice Hall, 2002
• http://java.sun.com/j2se/1.4.2/docs/guide/rmi/getstart.d
oc.html
• http://developer.java.sun.com/developer/onlineTraining
/rmi/RMI.html
• http://java.sun.com/j2se/1.4/docs/relnotes/features.htm
l
• http://java.sun.com/marketing/collateral/javarmi.html