Te 2403 Eval
Te 2403 Eval
Chapter 13:
Copy
2) RMI Architecture................................................................................................... 13-3
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-1
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
Introduction
Evaluation
• The Remote Method Invocation (RMI) model represents a
distributed object application.
RMI allows an object inside a JVM (a client) to invoke a method
Copy
on an object running on a remote JVM (a server) and have the
results returned to the client.
• Therefore, RMI implies a client and a server.
Evaluation
object.
• The reference is referred to as a remote object reference.
Copy
the same syntax as a method invocation on a local object.
RMI Architecture
Evaluation
• The interface that the client and server objects use to
interact with each other is provided through
stubs/skeleton, remote reference, and transport layers.
Copy
Stubs and skeletons are Java objects that act as proxies to the
client and server, respectively.
• All the network-related code is placed in the stub and
skeleton, so that the client and server will not have to deal
with the network and sockets in their code.
The remote reference layer handles the creation of and
management of remote objects.
The transport layer is the protocol that sends remote object
requests across the network.
Client Server
Stub Skeleton
Remote Reference Layer Remote Reference Layer
Transport Layer Transport Layer
Network Connection
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-3
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
Evaluation
• The server's job is to accept requests from a client,
perform some service, and then send the results back to
the client.
Copy
The server must specify an interface that defines the methods
available to clients as a service.
• This remote interface defines the client view of the remote
object.
Evaluation
All methods defined in the remote interface are required to state
that they throw a RemoteException.
Copy
exceptions that may occur during the execution of a remote
method call.
Evaluation
• An implementation of the CalendarTask interface is
shown below.
The implementation is referred to as the remote object.
Copy
The implementation class extends UnicastRemoteObject to
link into the RMI system.
• This is not a requirement. A class that does not extend
UnicastRemoteObject may use its exportObject()
method to be linked into RMI.
When a class extends UnicastRemoteObject, it must
provide a constructor declaring that it may throw a
RemoteException object.
• When this constructor calls super(), it activates code in
UnicastRemoteObject, which performs the RMI linking
and remote object initialization.
CalendarImpl.java
1. package examples.rmi;
2. import java.rmi.RemoteException;
3. import java.rmi.server.UnicastRemoteObject;
4. import java.util.Calendar;
5.
6. public class CalendarImpl extends UnicastRemoteObject
7. implements CalendarTask {
Evaluation
8.
9. private int counter = 1;
10.
11. public CalendarImpl() throws RemoteException {}
12.
13. public Calendar getDate() throws RemoteException{
Copy
14. System.out.print("Method called on server:");
15. System.out.println("counter = " + counter++);
16. return Calendar.getInstance();
17. }
18. }
Evaluation
• The server creates the remote object, registers it under
some arbitrary name, then waits for remote requests.
The java.rmi.registry.LocateRegistry class allows
Copy
the RMI registry service (provided as part of the JVM) to be
started within the code by calling its createRegistry
method.
• This could have also been achieved by typing the following
at a command prompt: rmiregistry.
• The default port for RMI is 1099.
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-6
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
1.
2.
3.
Evaluation
CalendarServer.java
package examples.rmi;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
Copy
4.
5. public class CalendarServer {
6.
7. public static void main(String args[]) {
8. System.out.println("Starting server...");
9. // Start RMI registry service and bind
10. // object to the registry
11. try {
12. LocateRegistry.createRegistry(1099);
13. Naming.rebind("TheCalendar",
14. new CalendarImpl());
15. } catch (Exception e) {
16. e.printStackTrace();
17. System.exit(1);
18. }
19. System.out.println("Server ready");
20. }
21. }
Evaluation
generation of stub classes.
• Java SE 5 adds support for the dynamic generation of stub
classes at runtime, eliminating the need to use the RMI stub
compiler, rmic, to pre-generate stub classes for remote
Copy
objects.
• Note that rmic must still be used to pre-generate stub
classes for remote objects that need to support clients
running on earlier versions.
Evaluation
• If RMI is being used with a version of Java prior to Java
SE 5, a stub must be generated on the server-side and
made available to the client.
Copy
The RMI compiler (rmic) is a tool used to create any
necessary stubs and/or skeletons to support the remote object.
• Skelton(s) have been optional since Java SE 1.2.
Evaluation
server.
• If the stub class is not available locally to the client, it must
be loaded dynamically over the network.
• Keep in mind that this is only necessary if a version of Java
Copy
prior to Java SE 5 is being used.
Evaluation
• An RMI client is a program that accesses the services
provided by a remote object.
The java.rmi.registry.LocateRegistry class allows
Copy
the RMI registry service to be located by a client by its
getRegistry method.
Evaluation
13. host = args[0];
14. try {
15. Registry r =
16. LocateRegistry.getRegistry(host, 1099);
17. Object o = r.lookup("TheCalendar");
18. remoteObj = (CalendarTask) o;
19. c = remoteObj.getDate();
20.
21.
22.
23.
24.
Copy }
} catch (Exception e) {
}
e.printStackTrace();
System.out.printf("%tc", c);
25. }
Evaluation
• The arguments to a remote method must be
Serializable.
They must be primitive types or objects that implement the
Copy
Serializable interface.
The same restriction applies to return values.
Evaluation
java.rmi.MarshalException is thrown.
Evaluation
• If the client stub class is not available in the local
CLASSPATH, it must be loaded dynamically over the
network.
Copy
This is a typical scenario when the client and server are not
running on the same machine.
We will illustrate downloading of stub classes via a web server.
Evaluation
The final issue is that the default Java security policy does not
allow all the networking operations required to load a class from
a remote host.
• An RMI client that needs to load classes remotely must have
Copy
a policy file granting the necessary permissions.
• The name of the policy file can be specified on the command
line by setting the java.security.policy property.
Evaluation
• The RMI application shown below illustrates dynamic
loading of stub classes.
It also shows an example of a Remote object used as a method
Copy
argument.
Following the source code are detailed instructions on how to
run the Client and Server.
Evaluation
17. public void transfer(double amt, Account src)
18. throws RemoteException;
19. }
Copy
the next page.
2.
3.
Evaluation
AccountImpl.java
1. package examples.rmi;
import java.rmi.server.*;
Copy
4. import java.rmi.*;
5.
6. public class AccountImpl extends UnicastRemoteObject
7. implements Account {
8. private double balance = 0.0;
9. private String name = "";
10.
11. public AccountImpl(String aName)
12. throws RemoteException {
13. name = aName;
14. }
15.
16. public String getName() throws RemoteException {
17. return name;
18. }
19.
20. public double getBalance()
21. throws RemoteException {
22. return balance;
23. }
24.
25. public void withdraw(double amt)
26. throws RemoteException {
27. if (amt > balance)
28. throw new RemoteException();
29. balance -= amt;
30. }
Evaluation
31.
32. public void deposit(double amt)
33. throws RemoteException {
34. balance += amt;
35. }
36.
Copy
37. public void transfer(double amt, Account src)
38. throws RemoteException {
39. src.withdraw(amt);
40. this.deposit(amt);
41. }
42. }
Evaluation
• The Server is shown below with the following features.
The compiling of the stub class for the client is done using
Runtime.exec().
Copy
• The exec method allows the JVM to run an external process
(in this case the rmi compiler - rmic).
The server creates and starts the registry service.
AccountServer.java
1. package examples.rmi;
2.
3. import java.io.IOException;
4. import java.net.InetAddress;
5. import java.rmi.registry.*;
6.
7. public class AccountServer {
8. private static String buildCommandLine(){
9. String jcp = "java.class.path";
10. StringBuffer sb = new StringBuffer();
11. sb.append('"');
12. sb.append(System.getProperty(jcp));
13. sb.append('"');
14. String classpath = sb.toString();
15. sb.setLength(0);
16. sb.append("rmic -d ").append(classpath);
17. sb.append(" -classpath ").append(classpath);
18. sb.append(" examples.rmi.AccountImpl");
19. System.out.println(sb.toString());
Evaluation
20. return sb.toString();
21. }
22. public static void main(String args[]) {
23. // execute rmic as an external process
24. Process p = null;
25. try {
Copy
26. String command = buildCommandLine();
27. p = Runtime.getRuntime().exec(command);
28. p.waitFor(); // wait for completion
29. } catch (Exception e1) {
30. e1.printStackTrace();
31. }
33.
34.
Evaluation
AccountServer.java - continued
32.
try {
String key = "java.rmi.server.codebase";
Copy
35. InetAddress server =
36. InetAddress.getLocalHost();
37. String address = server.getHostAddress();
38. String value =
39. "http://" + address + ":8080/";
40. System.setProperty(key, value);
41. //Start the StubServer
42. Thread t = new StubServer();
43. t.start();
44. // Create registry service
45. Registry reg =
46. LocateRegistry.createRegistry(1099);
47. // Create some Accounts
48. AccountImpl acct1 =
49. new AccountImpl("Alan");
50. AccountImpl acct2 =
51. new AccountImpl("Dave");
52.
53. // Register with the naming registry.
54. reg.rebind("Alan", acct1);
55. reg.rebind("Dave", acct2);
56.
57. System.out.println("Accts registered");
58. } catch (Exception e) {
59. e.printStackTrace();
60. }
61. }
Evaluation
62. }
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-15
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
Evaluation
• Although a web server such as Tomcat, WebLogic, or
WebSphere could be used to host the stub class
necessary for dynamic loading of the stub class, the file
Copy
below is a simple web server based on the code from the
Networking chapter of this course.
StubServer.java
1. package examples.rmi;
2.
3. import java.io.*;
4. import java.net.*;
5.
6. public class StubServer extends Thread {
7.
8. static byte[] hdrNotFound =
9. "HTTP/1.0 404 Not Found\n\n".getBytes();
10. static byte[] notFound =
11. "<html>Resource Not Found</html>".getBytes();
12. static byte[] hdrOK =
13. "HTTP/1.0 200 OK\n\n".getBytes();
14. static byte[] testResponse =
15. "<html>Server operational</html>".getBytes();
16.
17. public void run() {
18. ServerSocket theServer = null;
19. Socket clientSocket;
20. // Attempt to start the server
21. try {
22. theServer = new ServerSocket(8080);
23.
24.
25.
26.
27.
Evaluation while (true) {
}
clientSocket = theServer.accept();
handleClient(clientSocket);
33.
34.
35.
Evaluation
StubServer.java - continued
private void handleClient(Socket cSocket) {
OutputStream toClient = null;
BufferedReader fromClient = null;
Copy
36. try {
37. // Get Input and Output
38. fromClient = new BufferedReader(
39. new InputStreamReader(cSocket
40. .getInputStream()));
41. toClient = cSocket.getOutputStream();
42. // read from Client
43. String theLine = fromClient.readLine();
44. String request = theLine.split(" ")[1];
45. System.out.println("StubServer Request:"
46. + theLine);
47. if (request.equals("/")) {
48. toClient.write(hdrOK);
49. toClient.write(testResponse);
50. } else {
51. processStub(request, toClient);
52. }
53.
54. fromClient.close();
55. toClient.close();
56. cSocket.close();
57. } catch (IOException ioe) {
58. String msg = "Connection lost";
59. System.out.println(msg);
60. }
61. }
Continued on following page
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-17
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
62.
63.
64.
Evaluation
StubServer.java - continued
private void processStub(String req,
OutputStream toClient){
InputStream is =
Copy
65. this.getClass().getResourceAsStream(req);
66.
67. byte[] bufferedStub = null;
68. try {
69. if (is != null) {
70. int size = is.available();
71. bufferedStub = new byte[size];
72. is.read(bufferedStub);
73. is.close();
74. toClient.write(hdrOK);
75. toClient.write(bufferedStub);
76. } else {
77. toClient.write(hdrNotFound);
78. toClient.write(notFound);
79. }
80. } catch (IOException e) {
81. e.printStackTrace();
82. }
83. }
84. }
Evaluation
2.
3. import java.net.URL;
4. import java.rmi.*;
5. import java.rmi.registry.*;
6.
7. public class AccountClient {
8. public static void main(String args[]) {
9.
10.
11.
12.
13.
Copy String host = "localhost";
if (args.length > 0) { host = args[0]; }
try {
String key = "java.security.policy";
Class c = AccountClient.class;
14. URL u =c.getResource("policy.client");
15.
16.
17.
Evaluation
AccountClient.java - continued
String value = u.getPath();
System.setProperty(key, value);
System.setSecurityManager(
Copy
18. new RMISecurityManager());
19. Registry r =
20. LocateRegistry.getRegistry(host, 1099);
21. // Lookup Account objects
22. Account act1 =
23. (Account) r.lookup("Alan");
24. Account act2 =
25. (Account) r.lookup("Dave");
26.
27. showBalance(act1);
28. showBalance(act2);
29.
30. // Make some deposits
31. act1.deposit(200);
32. act2.deposit(100);
33.
34. // Show results
35. System.out.println("Deposit 200 & 100");
36. showBalance(act1);
37. showBalance(act2);
38.
39. // Do a transfer
40. act2.transfer(10, act1);
41.
42. // Show results
43. System.out.println("Transfer 10");
44. showBalance(act1);
Evaluation
45. showBalance(act2);
46. } catch (Exception e){ e.printStackTrace(); }
47. }
48.
49. public static void showBalance(Account acct)
50. throws RemoteException {
Copy
51. System.out.println("Balance for " +
52. acct.getName() + " is " +
53. acct.getBalance());
54. }
55. }
Evaluation
• Running the AccountServer will accomplish the
following.
It generates the AccountImpl_Stub needed by the client so
Copy
that it can be dynamically loaded by the client.
It starts the StubServer so that the AccountImpl_Stub is
available via the java.rmi.server.codebase property.
It starts the rmi registry to bind the remote Account objects.
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-20
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
Exercises
Evaluation
1. Build and test an implementation for a MathServices
interface with remote methods as shown below.
public double sqroot (double value);
Copy
public double square(double value);
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-21
ADVANCED JAVA PROGRAMMING CHAPTER 13: REMOTE METHOD INVOCATION (RMI)
Evaluation
Copy
Evaluation
Copy
©2009 /training/etc Inc. REPRODUCTION OF THESE MATERIALS IS PROHIBITED.
13-22