Title: RMI Classnote
1RMIClassnote13
2Define the functions of the remote class as an
interface
- A remote object is an instance of a class that
implements a Remote interface. - A Remote interface will declare each of the
methods that you would like to call from other
JavaTM virtual machines (JVMs)
3Characteristics of an interface
- The remote interface must be declared public.
- Otherwise, a client will get an error when
attempting to load a remote object that
implements the remote interface, unless that
client is in the same package as the remote
interface. - The remote interface extends the java.rmi.Remote
interface. - Each method must declare java.rmi.RemoteException
(or a superclass of RemoteException) in its
throws clause, in addition to any
application-specific exceptions. - 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).
4Interface
- Here is the interface definition for the remote
interface, examples.hello.Hello. - The interface contains just one method, sayHello,
which returns a string to the caller - package examples.hello
- import java.rmi.Remote
- import java.rmi.RemoteException
- public interface Hello extends Remote
-
- String sayHello() throws RemoteException
-
5Interface (cont.)
- Remote method invocations can fail in very
different ways from local method invocations - network-related communication problems and
- server problems
- remote methods will report communication failures
by throwing a java.rmi.RemoteException.Â
6server classes
- 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()
-
-
- public String sayHello()
- return "Hello World!"
-
7server classes (cont.)
- 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("//myhost/HelloServer", obj)
-
- System.out.println("HelloServer bound in
registry") - catch (Exception e)
- System.out.println("HelloImpl err "
e.getMessage()) - e.printStackTrace()
-
-
8server classes
- At a minimum, a remote object implementation
class must - Declare that it implements at least one remote
interface - Define the constructor for the remote object
- Provide implementations for the methods that can
be invoked remotely
9server classes
- A "server" class is the class which has a main
method that - creates an instance of the remote object
implementation, and - binds that instance to a name in the rmiregistry.
10server classes
- The class that contains this main method could be
- the implementation class itself, or
- another class entirely.
11Main method
- the main method is part of examples.hello.HelloImp
l - The server program needs to
- Create and install a security manager
- 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
12Summery of tasks
- Implement a remote interface
- Define the constructor for the remote object
- Provide an implementation for each remote method
- Create and install a security manager
- 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
131. Implement a remote interface
- In the Java programming language, when a class
declares that it implements an interface, a
contract is formed between the class and the
compiler. - By entering into this contract, the class is
promising that it will provide method bodies, or
definitions, for each of the method signatures
declared in that interface. - Interface methods are implicitly public and
abstract, - if the implementation class doesn't fulfill its
contract, it becomes by definition an abstract
class, - the compiler will point out this fact if the
class was not declared abstract.
141. Implement a remote interface
- The implementation class in this example is
examples.hello.HelloImpl. - Here is the HelloImpl class declaration
- public class HelloImpl extends UnicastRemoteObject
implements Hello -
- As a convenience, the implementation class can
extend a remote class, which in this example is
java.rmi.server.UnicastRemoteObject.
151. Implement a remote interface
- By extending 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
- If you want a remote object that can be activated
(created) when a client requests it, rather than
running all the time, after you finish this
tutorial, you can take a look at the RMI
Activation tutorial. - Also, you can learn about how to use your own
communication protocol, rather than the TCP
sockets that RMI uses by default, in the tutorial
on Using a Custom RMI Socket Factory.
162. Define the constructor for the remote object
- The constructor for a remote class provides the
same functionality as the constructor for a
non-remote class - It initializes the variables of each newly
created instance of the class, and returns an
instance of the class to the program which called
the constructor. - In addition, the remote object instance will need
to be "exported". - Exporting a remote object makes it available to
accept incoming remote method requests, by
listening for incoming calls to the remote object
on an anonymous port. - When you extend java.rmi.server.UnicastRemoteObjec
t or java.rmi.activation.Activatable, your class
will be exported automatically upon creation.
172. Define the constructor for the remote object
- If you choose to extend a remote object from any
class other than UnicastRemoteObject or
Activatable, you will need to explicitly export
the remote object by calling either the
UnicastRemoteObject.exportObject method or the
Activatable.exportObject method from your class's
constructor (or another initialization method, as
appropriate). - Because the object export could potentially throw
a java.rmi.RemoteException, you must define a
constructor that throws a RemoteException, even
if the constructor does nothing else. - If you forget the constructor, javac will produce
the following error message - HelloImpl.java13 Exception java.rmi.RemoteExcept
ion must be caught, or it must be declared in the
throws clause of this method. super() 1
error
18Summary The implementation class for a remote
object needs to
- Implement a remote interface
- Export the object so that it can accept incoming
remote method calls - Declare its constructor(s) to throw at least a
java.rmi.RemoteException
19Constructor
- Here is the constructor for the
examples.hello.HelloImpl class -
- public HelloImpl() throws RemoteException
-
- super()
-
20Note the following
- The super method call invokes the no-argument
constructor of java.rmi.server.UnicastRemoteObject
, which exports the remote object. - The constructor must throw java.rmi.RemoteExceptio
n, because RMI's attempt to export a remote
object during construction might fail if
communication resources are not available. - Calling is for clarity because by default it is
called
213. Provide an implementation for each remote
method
- public String sayHello() throws RemoteException
-
- return "Hello World!"
-
- 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. - Most of the core classes in java.lang and
java.util implement the Serializable interface.
223. Provide an implementation for each remote
method
- 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. - Stubs are described fully in the Java Remote
Method Invocation Specification. - We'll create them later in this tutorial in the
section Use rmic to generate stubs and
skeletons.
23Note
- A class can define methods not specified in the
remote interface, but those methods can only be
invoked within the virtual machine running the
service and cannot be invoked remotely.
244. Create and install a security manager
- The main method of the server first needs to
create and install a security manager either the
RMISecurityManager or one that you have defined
yourself. - For example
- if (System.getSecurityManager() null)
-
- System.setSecurityManager(new
RMISecurityManager()) -
254. Create and install a security manager
- A security manager needs to be running so that it
can guarantee that the classes that get loaded do
not perform operations that they are not allowed
to perform. - 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. - In this example, a security manager is not
installed in the client code because applets use
the security manager already installed in the
client browser.
264. Create and install a security manager (cont.)
- If the client were an application rather than an
applet, however, you would need to use the same
procedure as is used above to install a security
manager in the client. - 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).
275. Create one or more instances of a remote
object
- The main method of the server needs to create one
or more instances of the remote object
implementation which provides the service. - For example
- HelloImpl obj new HelloImpl()
- The constructor exports the remote object, which
means that once created, the remote object is
ready to accept incoming calls.
286. Register the remote object
- For a caller (client, peer, or applet) to be able
to invoke a method on a remote object, that
caller must first obtain a reference to the
remote object. - For bootstrapping, the RMI system provides a
remote object registry that allows you to bind a
URL-formatted name of the form "//host/objectname"
to the remote object, where objectname is a
simple string name.
296. Register the remote object
- The RMI registry is a simple server-side name
service that allows remote clients to get a
reference to a remote object. - It is typically used only to locate the first
remote object an RMI client needs to talk to. - Then that first object would in turn provide
application-specific support for finding other
objects.
306. Register the remote object
- For example, the reference can be obtained as a
parameter to, or a return value from, another
remote method call. - Once a remote object is registered on the server,
callers can look up the object by name, obtain a
remote object reference, and then remotely invoke
methods on the object. - For example, the following code binds the name
"HelloServer" to a reference for the remote
object - Naming.rebind("//myhost/HelloServer", obj)
31Note the following about the arguments to the
rebind method call
- The first parameter is a URL-formatted
java.lang.String, representing the location and
name of the remote object. - No protocol needs to be specified in the
URL-formatted string. - You will need to change the value of myhost to be
the name or IP address of your server machine
otherwise, the remote object host defaults to the
current host. - For example, "HelloServer" is a valid name string
that refers to a remote object bound to the name
HelloServer, running on the local host.
32Note the following about the arguments to the
rebind method call
- Optionally, a port number can be supplied in the
URL-formatted string. - Specifying the port number is necessary when the
registry that needs to be contacted is running on
a port other than the default port, 1099. - For example, "//myhost1234/HelloServer" is a
valid name string for the HelloServer remote
object, reachable through an RMI registry that is
running on the host myhost and is listening for
incoming calls on port 1234.
33Note the following about the arguments to the
rebind method call
- The second parameter is a reference to the object
implementation, on which remote methods will be
invoked. - Once an object is exported, the RMI runtime
substitutes a reference to the remote object's
stub for the actual remote object reference
specified by the obj argument. - When a client performs a lookup in a server's
remote object registry, a serialized instance of
the stub for the implementation is returned.
34Write a client program that uses the remote
service
- Here is the HTML code for the web page that
references the Hello World 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 "blank"
-
- // "obj" is the identifier that we'll use to
refer - // to the remote object that implements the
"Hello" - // interface
- Hello obj null
-
35Write a client program that uses the remote
service
- public void init()
- try
- obj (Hello)Naming.lookup("//"
- getCodeBase().getHost()
"/HelloServer") - message obj.sayHello()
- catch (Exception e)
- System.out.println("HelloApplet
exception " e.getMessage()) - e.printStackTrace()
-
-
- public void paint(Graphics g)
- g.drawString(message, 25, 50)
-
36Write a client program that uses the remote
service
- First, the applet gets a reference to the remote
object implementation (advertised as
"HelloServer") from the server host's
rmiregistry. Like the Naming.rebind method, the
Naming.lookup method takes a URL-formatted
java.lang.String. - In this example, the applet constructs the URL
string by using the getCodeBase method in
conjunction with the getHost method.
37Naming.lookup takes care of the following tasks
- Constructing a registry stub instance (to contact
the server's registry) using the hostname and
port number supplied as arguments to
Naming.lookup - Using the registry stub to call the remote lookup
method on the registry, using the URL's name
component ("HelloServer") - The registry returns the HelloImpl_Stub instance
bound to that name - The lookup method receives the remote object's
(HelloImpl) stub instance and loads the stub
class (examples.hello.HelloImpl_Stub) from the
CLASSPATH or the applet's codebase - Naming.lookup returns the stub to its caller
(HelloApplet)
38Naming.lookup takes care of the following tasks
- The applet invokes the remote sayHello method on
the server's remote object - RMI serializes and returns the reply string
"Hello World!" - RMI deserializes the string and stores it in a
variable named message. - The applet invokes the paint method, causing the
string "Hello World!" to be displayed in the
drawing area of the applet.
39Note
- The URL-formatted string that is passed as a
parameter to the Naming.lookup method must
include the server's hostname. - Otherwise, the applet's lookup attempt will
default to the client, and the AppletSecurityManag
er will throw an exception because the applet
cannot access the local system, but is instead
limited to only communicating with the applet's
host.
40Hello World applet
-
- Hello World
- Hello World
-
- code"examples.hello.HelloApplet"
- width500 height120
-
-
41Note
- There needs to be an HTTP server running on the
machine from which you want to download classes. - The codebase in the HTML file specifies a
directory below the directory from which the web
page was itself loaded. - Using this kind of relative path is usually a
good idea. For example, if the codebase directory
(where the applet's class files live), referenced
by the applet's HTML, was in the directory above
the the HTML directory, you would use the
relative path, "../". - The applet's code attribute specifies the
fully-qualified package name of the applet, in
this example examples.hello.HelloApplet
code"examples.hello.HelloApplet"