remote object

Download Report

Transcript remote object

RMI
Classnote#13
1
Define 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)
2
Characteristics 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).
3
Interface
• 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;
}
4
Interface (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.
5
server 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!";
}
6
server 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();
}
}
}
7
server classes
At a minimum, a remote object
implementation class must:
1. Declare that it implements at least one
remote interface
2. Define the constructor for the remote
object
3. Provide implementations for the
methods that can be invoked remotely
8
server 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.
9
server classes
The class that contains this main method
could be
• the implementation class itself, or
• another class entirely.
10
Main method
• the main method is part of
examples.hello.HelloImpl
• 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
11
Summery of tasks
1. Implement a remote interface
2. Define the constructor for the remote object
3. Provide an implementation for each remote method
4. Create and install a security manager
5. Create one or more instances of a remote
object
6. Register at least one of the remote objects with
the RMI remote object registry, for
bootstrapping purposes
12
1. 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.
13
1. 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.
14
1. 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.
15
2. 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.UnicastRemoteObject
or java.rmi.activation.Activatable, your class will be
exported automatically upon creation.
16
2. 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.java:13: Exception java.rmi.RemoteException must be caught,
or it must be declared in the throws clause of this method.
super(); ^ 1 error
17
Summary: 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
18
Constructor
• Here is the constructor for the
examples.hello.HelloImpl class:
public HelloImpl() throws RemoteException
{
super();
}
19
Note 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.RemoteException, 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
20
3. 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.
21
3. 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.
22
Note
• 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.
23
4. 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());
}
24
4. 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.
25
4. 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).
26
5. 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.
27
6. 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.
28
6. 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.
29
6. 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);
30
Note 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 URLformatted 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.
31
Note the following about the
arguments to the rebind method call
– Optionally, a port number can be supplied in the URLformatted 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, "//myhost:1234/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.
32
Note 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.
33
Write 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;
34
Write 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);
}
}
35
Write a client program that uses the
remote service
1. 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.
36
Naming.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)
37
Naming.lookup takes care of the
following tasks:
2. 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.
3. The applet invokes the paint method,
causing the string "Hello World!" to be
displayed in the drawing area of the
applet.
38
Note
• 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
AppletSecurityManager will throw an exception
because the applet cannot access the local
system, but is instead limited to only
communicating with the applet's host.
39
Hello World applet
<HTML>
<title>Hello World</title>
<center> <h1>Hello World</h1> </center>
<applet codebase="myclasses/"
code="examples.hello.HelloApplet"
width=500 height=120>
</applet>
</HTML>
40
Note
• 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"
41