Sponsored Link •
|
java.rmi.Remote
java.rmi.RemoteException
in
its throws clause
Summer
Interface1 // 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
Class1 // 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.class
rmic SummerImplGives youSummerImpl_Stub.class
andSummerImpl_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 int
s together, ignoring overflow, and return a Long
result. Run ProductClient
, making sure that Multiplication.class
is
downloaded dynamically by WorkerImpl
.
Sponsored Links
|