|
|
|
Sponsored Link •
|
java.rmi.Remote
java.rmi.RemoteException in
its throws clause
Summer Interface
1 // In file rmi/ex1/Summer.java
2 import java.rmi.*;
3
4 public interface Summer extends Remote {
5
6 long sumString(String s)
7 throws InvalidLongException,
8 RemoteException;
9 }
10
1 // In file rmi/ex1/InvalidLongException.java
2 public class InvalidLongException
3 extends Exception {
4
5 private String message;
6 InvalidLongException(String s) {
7 message = s;
8 }
9 public String getMessage() {
10 return message;
11 }
12 }
java.rmi.server.UnicastRemoteObject:
java.rmi.RemoteException
SummerImpl Class
1 // In file rmi/ex1/SummerImpl.java
2 import java.rmi.*;
3 import java.rmi.server.*;
4 import java.io.*;
5 import java.util.StringTokenizer;
6
7 public class SummerImpl
8 extends UnicastRemoteObject
9 implements Summer {
10
11
12
13 public SummerImpl() throws RemoteException {
14 }
15
16 public long sumString(String s)
17 throws InvalidLongException, RemoteException {
18 long sum = 0;
19 StringTokenizer st = new StringTokenizer(s);
20 String token;
21 while (st.hasMoreTokens()) {
22 token = st.nextToken();
23 try {
24 sum += Long.parseLong(token);
25 }
26 catch (NumberFormatException e) {
27 throw new InvalidLongException(
28 "Invalid number: " + token);
29 }
30 }
31
32 return sum;
33 }
34 }
RMISecurityManager
//localhost/SUMMER //127.0.0.1/SUMMER //localhost:1099/SUMMER SUMMER
SummerServer
1 // In file rmi/ex1/SummerServer.java
2 import java.rmi.*;
3
4 public class SummerServer {
5
6
7
8 public static void main(String[] args) {
9
10 System.setSecurityManager(
11 new RMISecurityManager());
12 try {
13 SummerImpl summer = new SummerImpl();
14 System.out.println("Ready to rebind");
15 Naming.rebind("SUMMER", summer);
16 System.out.println("Ready to sum");
17 }
18 catch(Exception e) {
19 e.printStackTrace();
20 }
21 }
22 }
Naming.lookup()
Naming.lookup():
Naming.rebind()
SummerClient
1 // In file rmi/ex1/SummerClient.java
2 import java.rmi.*;
3 import java.rmi.registry.*;
4 import java.net.*;
5 import java.io.*;
6
7 public class SummerClient {
8 public static void main(String[] args) {
9
10 System.setSecurityManager(
11 new RMISecurityManager());
12
13 try {
14
15 Summer summer = (Summer) Naming.lookup(
16 "rmi://localhost:1099/SUMMER");
17
18 LineNumberReader stdinReader =
19 new LineNumberReader(new BufferedReader(
20 new InputStreamReader(System.in)));
21
22 for (;;) {
23
24 String userLine = stdinReader.readLine();
25 if (userLine == null
26 || userLine.length() == 0) {
27 break;
28 }
29 String outString;
30
31 try {
32 long sum = summer.sumString(userLine);
33 outString = Long.toString(sum);
34 }
35 catch(InvalidLongException e) {
36 outString = e.getMessage();
37 }
38 System.out.println(outString);
39 }
40 }
41 catch (Exception e) {
42 e.printStackTrace();
43 }
44 }
45 }
46
rmic:
javac SummerImpl.javaGives youSummerImpl.classrmic SummerImplGives youSummerImpl_Stub.classandSummerImpl_Skel.class
start rmiregistry
java -Djava.security.policy=policy SummerServer
java -Djava.security.policy=policy SummerClient
grant {
// Allow everything for now
permission java.security.AllPermission;
};
1 package com.artima.compserv;
2
3 import java.rmi.Remote;
4 import java.rmi.RemoteException;
5
6 public interface Worker extends Remote {
7
8 Object doJob(Job job)
9 throws RemoteException, JobException;
10 }
1 package com.artima.compserv;
2
3 public interface Job extends java.io.Serializable {
4
5 Object doJob()
6 throws JobException;
7 }
1 package com.artima.compserv;
2
3 public class JobException extends Exception {
4
5 public JobException() {
6 }
7
8 public JobException(String msg) {
9 super(msg);
10 }
11 }
1 package com.artima.compserv;
2
3 public class Addition implements Job {
4
5 private long[] addends;
6
7 public Addition(long[] addends) {
8 this.addends = addends;
9 }
10
11 public Object doJob() {
12
13 int len = addends.length;
14
15 long sum = 0;
16 for (int i = 0; i < len; ++i) {
17 sum += addends[i];
18 }
19
20 return new Long(sum);
21 }
22 }
Bill Venners: I heard the story that originally Java was envisioned for embedded devices. To what extent was Java designed with what would eventually come to be called Jini in mind? In other words, were you just thinking about embedded devices, or were you thinking about a Jini-like world?
James Gosling: Oddly enough, something very much like the Jini world was in there from day one. The very early version of Java, which was called Oak and ran on the Star Sevens, had a distributed message system in it that was very much like RMI.
Bill Joy: We built the JVM to let objects move around.
RMI/ex2/server directory, define an implementation of the Worker interface
named WorkerImpl that extends UnicastRemoteObject. WorkerImpl's
constructor must include RemoteException in its throws clause.
The WorkerImpl's doJob() method should invoke doJob() on
the passed Job object and pass the Object returned by Job's
doJob() method back to its caller of WorkerImpl's doJob()
method.
RMI/ex2/server directory, define a server named WorkerServer, which:
WorkerImpl
WorkerImpl in RMIRegistry with the name "WORKER"
WorkerImpl, by running this command in the
RMI/ex2/server directory:
rmic WorkerImpl
Start RMIRegistry from RMI/ex2/server
(the directory in which you created the stub and skeletons), with this command:
start RMIRegistry
Lastly, start your server with this command from RMI/ex2/server:
java -Djava.security.policy=policy.all WorkerServer
Copy SummerClient from the RMI/ex1 directory to the RMI/ex2/client directory.
Change SummerClient so that it grabs the "WORKER" service instead of
the "SUMMER" service. When the user types in a string of numbers, create a new
Addition object and pass it to the Worker object's doJob()
method. Cast the returned Object to Long, convert the Long
to a String and print it out.
Addition.class must be in a location where the server can find it locally,
which is why it is sitting in the RMI/ex2/server/com/artima/compserv directory.
In addition, Addition.class must be available to the client, which is why it
is sitting in the REMI/ex2/client/com/artima/compserv directory.
Start your client in the RMI/ex2/client directory with the following command:
java -Djava.security.policy=policy.all SummerClient
Type in a few strings of numbers and make sure they get summed correctly.
Now try running your program such that the Addition.class file will be dynamically
downloaded by the Worker server.
First, place Addition.class in a JAR file named add.jar. To do this, just
execute the following command in the RMI/ex2/client directory:
jar cf add.jar com/artima/compserv/Addition.class
Move this JAR file to the directory from which code will be downloaded, C:\client-dl.
Remove Addition.class from the server's class path, so that the server
can't find Addition.class locally:
del RMI\ex2\server\com\artima\compserv\Addition.class
Start a web server running on RMI/ex2/client-dl, the directory in which you placed add.jar.
The following
command would be appropriate assuming Jini was installed in c:\jini1_0_1 and the add.jar
file was installed in C:\OAJCode\RMI\examples\ex2\client-dl:
start java -jar c:\jini1_0_1\lib\tools.jar -dir C:\OAJCode\RMI\examples\ex2\client-dl -port 8080 -verbose
Kill and restart the Worker server from the same directory (RMI/ex2/server)
using the same command:
java -Djava.security.policy=policy.all WorkerServerFinally, restart the client from
RMI/ex2/client, this time specifying the
java.rmi.server.codebase property, as in:
java -Djava.security.policy=policy.all -Djava.rmi.server.codebase=http://127.0.0.1:8080/add.jar SummerClient
Try typing in numbers and see if they get added. Once you get this working, make sure you can explain how it is working.
Rearrange things a bit so that the stub for WorkerImpl is downloaded dynamically
by RMIRegistry.
Kill RMIRegistry, the WorkerServer and client. Start RMIRegistry from the RMI directory,
where it won't be able to load the stub class (WorkerImpl_Stub) locally. Copy
WorkerImpl_Stub.class to the RMI/ex2/server-dl directory. Also copy Worker.class,
Job.class, and JobException.class to the RMI/ex2/server-dl/com/artima/compserv
directory, so that RMIRegistry will be able to find them. Start a web server
running on the server-dl directory, using a command such as:
start java -jar c:\jini1_0_1\lib\tools.jar -dir C:\OAJCode\RMI\ex2\server-dl -port 8081 -verbose
Now start your server from RMI/ex2/server again, this time specifying a codebase with a command like:
java -Djava.security.policy=policy.all -Djava.rmi.server.codebase=http://127.0.0.1:8081/ WorkerServer
Make sure you have the trailing slash ('/') on the codebase URL when you start WorkerServer.
Finally, restart the client from RMI/ex2/client, this time specifying the
java.rmi.server.codebase property, as in:
java -Djava.security.policy=policy.all -Djava.rmi.server.codebase=http://127.0.0.1:8080/add.jar SummerClient
In the RMI/ex2/client directory, copy your SummerClient.java
file to ProductClient.java. Create a
class Multiplication that implements Job. Multiplication's
constructor should take an array of int's. Its doJob() method should
multiply all the ints together, ignoring overflow, and return a Long
result. Run ProductClient, making sure that Multiplication.class is
downloaded dynamically by WorkerImpl.
|
Sponsored Links
|