![]() |
![]() |
Let's get started again.
The basic starting point.burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman burrowww.cs.indiana.edu% mkdir rmi2001 burrowww.cs.indiana.edu% cd rmi2001 burrowww.cs.indiana.edu% ls burrowww.cs.indiana.edu%
Let's see it running.burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/rmi2001 burrowww.cs.indiana.edu% ls -ld * -rw-r--r-- 1 dgerman faculty 386 Nov 13 09:48 Client.java -rw-r--r-- 1 dgerman faculty 263 Nov 13 09:48 Server.java burrowww.cs.indiana.edu% cat Server.java public class Server { public String remoteMethod() { try { return " the time is " + new java.util.Date() + "\n" + " on " + java.net.InetAddress.getLocalHost() + "\n"; } catch (Exception e) { return "Server error: " + e + " ...\n"; } } } burrowww.cs.indiana.edu% cat Client.java public class Client { public static void main(String[] args) { try { String time = null; Server remote = new Server(); System.out.println( "Client reporting from: (" + java.net.InetAddress.getLocalHost() + ") \n" + remote.remoteMethod()); } catch (Exception e) { System.out.println("Client error: " + e + "...\n"); } } } burrowww.cs.indiana.edu%
Easy, but notice one thing: the client controls everything. We do not need to start the server first. But in a networked context that will change, and we will have to bring the server up before we can run the client. Let's now write the networked version.burrowww.cs.indiana.edu% javac *.java burrowww.cs.indiana.edu% java Client Client reporting from: (burrowww.cs.indiana.edu/129.79.245.98) the time is Tue Nov 13 09:51:10 EST 2001 on burrowww.cs.indiana.edu/129.79.245.98 burrowww.cs.indiana.edu% java Client Client reporting from: (burrowww.cs.indiana.edu/129.79.245.98) the time is Tue Nov 13 09:51:14 EST 2001 on burrowww.cs.indiana.edu/129.79.245.98 burrowww.cs.indiana.edu%
Make a note of this link.burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/rmi2001 burrowww.cs.indiana.edu% ls -ld N*.java -rw-r--r-- 1 dgerman faculty 474 Nov 13 10:28 NClient.java -rw-r--r-- 1 dgerman faculty 889 Nov 13 10:27 NServer.java -rw-r--r-- 1 dgerman faculty 122 Nov 13 10:30 NServerAd.java burrowww.cs.indiana.edu% cat NServerAd.java public interface NServerAd extends java.rmi.Remote { public String remoteMethod() throws java.rmi.RemoteException; }
We try again, like last time.burrowww.cs.indiana.edu% cat NServer.java import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; public class NServer extends UnicastRemoteObject implements NServerAd { public String remoteMethod() { try { return " the time is " + new java.util.Date() + "\n" + " on " + java.net.InetAddress.getLocalHost() + "\n"; } catch (Exception e) { return "Server error: " + e + " ...\n"; } } public NServer() throws RemoteException { System.out.println("Server initialized... "); } public static void main(String[] args) { Registry reg; try { System.setSecurityManager(new RMISecurityManager()); NServer richard = new NServer(); reg = LocateRegistry.createRegistry(31287); reg.bind("Feynman", richard); System.out.println("Server ready... "); } catch (Exception e) { System.out.println("Server error " + e + "...\n"); } } } burrowww.cs.indiana.edu% cat NClient.java import java.rmi.*; public class NClient { public static void main(String[] args) { try { String time = null; NServerAd farAway = (NServerAd)Naming.lookup( "rmi://" + args[0] + ":31287/Feynman"); System.out.println( "Client reporting from: (" + java.net.InetAddress.getLocalHost() + ") \n" + farAway.remoteMethod() ); } catch (Exception e) { System.out.println("Client error: " + e + "...\n"); } } } burrowww.cs.indiana.edu%
It works now. So what's different?
burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/rmi2001 burrowww.cs.indiana.edu% ls -ld ~/.java* -rw-r--r-- 1 dgerman faculty 72 Nov 9 23:08 /u/dgerman/.java.policy burrowww.cs.indiana.edu% cat ~/.java* grant { permission java.net.SocketPermission "*", "connect,accept"; };burrowww.cs.indiana.edu%
(Many thanks to Rob Henderson for researching, and helping us with, this question).
If you ever wondered what's
the advantage of being part of a team you now have the answer.
So the question now is: where did we get this file?
Well, things have changed since November 1999, the date of the previous tutorial.
For one thing, as before, loading classes remotely needs a security manager. The default Java security policy, however, does not allow all the networking operations required to resolve a class from a remote host. (See Flanagan, see Oaks) So we need to have this specified somewhere.
Let's investigate this more closely. We work with other
burrow
machines.
These sessions are intertwined, so check the time stamps to see what happened.
On the server side:
On the client side:burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/rmi2001 burrowww.cs.indiana.edu% date Tue Nov 13 11:16:27 EST 2001 burrowww.cs.indiana.edu% ls -ld ~/.java* -rw-r--r-- 1 dgerman faculty 72 Nov 9 23:08 /u/dgerman/.java.policy burrowww.cs.indiana.edu% cat ~/.java.policy grant { permission java.net.SocketPermission "*", "connect,accept"; };burrowww.cs.indiana.edu% date Tue Nov 13 11:16:59 EST 2001 burrowww.cs.indiana.edu% java NServer Server initialized... Server ready... ^Cburrowww.cs.indiana.edu% burrowww.cs.indiana.edu% date Tue Nov 13 11:17:59 EST 2001 burrowww.cs.indiana.edu% mv ~/.java.policy ~/trickortreat burrowww.cs.indiana.edu% date Tue Nov 13 11:19:01 EST 2001 burrowww.cs.indiana.edu% java NServer Server initialized... Server ready... ^Cburrowww.cs.indiana.edu% burrowww.cs.indiana.edu% date Tue Nov 13 11:19:25 EST 2001 burrowww.cs.indiana.edu%
So the file is truly important.tucotuco.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/rmi2001 tucotuco.cs.indiana.edu% date Tue Nov 13 11:16:34 EST 2001 tucotuco.cs.indiana.edu% java NClient burrowww.cs.indiana.edu Client reporting from: (tucotuco.cs.indiana.edu/129.79.245.110) the time is Tue Nov 13 11:17:53 EST 2001 on burrowww.cs.indiana.edu/129.79.245.98 tucotuco.cs.indiana.edu% date Tue Nov 13 11:19:08 EST 2001 tucotuco.cs.indiana.edu% java NClient burrowww.cs.indiana.edu Client error: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: Connection refused... tucotuco.cs.indiana.edu%
Here, however, is another way of doing the same thing.
On the server side (sessions are still intertwined):
On the client side:burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/rmi2001 burrowww.cs.indiana.edu% ls -ld ../.java* No match burrowww.cs.indiana.edu% ls -ld ../trick* -rw-r--r-- 1 dgerman faculty 72 Nov 9 23:08 ../trickortreat burrowww.cs.indiana.edu% cat ../trick* grant { permission java.net.SocketPermission "*", "connect,accept"; };burrowww.cs.indiana.edu% date Tue Nov 13 11:33:20 EST 2001 burrowww.cs.indiana.edu% date; java -Djava.security.policy=../trickortreat NServer Tue Nov 13 11:34:10 EST 2001 Server initialized... Server ready... ^Cburrowww.cs.indiana.edu% date; java NServer Tue Nov 13 11:34:48 EST 2001 Server initialized... Server ready... ^Cburrowww.cs.indiana.edu%
So we can bypass the naming convention, but we can't do without doing something.tucotuco.cs.indiana.edu% pwd; date /nfs/paca/home/user1/dgerman/rmi2001 Tue Nov 13 11:33:27 EST 2001 tucotuco.cs.indiana.edu% date; java NClient burrowww.cs.indiana.edu Tue Nov 13 11:34:15 EST 2001 Client reporting from: (tucotuco.cs.indiana.edu/129.79.245.110) the time is Tue Nov 13 11:34:36 EST 2001 on burrowww.cs.indiana.edu/129.79.245.98 tucotuco.cs.indiana.edu% date; java NClient burrowww.cs.indiana.edu Tue Nov 13 11:34:58 EST 2001 Client error: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: Connection refused... tucotuco.cs.indiana.edu%
Now let's try a more sophisticated development.
We'll discuss this in class.burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/chat2001 burrowww.cs.indiana.edu% ls -ld *.java -rw-r--r-- 1 dgerman faculty 1469 Nov 13 14:17 ChatClient.java -rw-r--r-- 1 dgerman faculty 1138 Nov 13 16:08 ChatServer.java -rw-r--r-- 1 dgerman faculty 135 Nov 13 16:07 ClientExports.java -rw-r--r-- 1 dgerman faculty 208 Nov 13 16:08 ServerExports.java burrowww.cs.indiana.edu% cat ClientExports.java import java.rmi.*; public interface ClientExports extends Remote { public void update(String message) throws RemoteException; } burrowww.cs.indiana.edu% cat ServerExports.java import java.rmi.*; public interface ServerExports extends Remote { public void register(ClientExports client) throws RemoteException; public void broadcast(String message) throws RemoteException; } burrowww.cs.indiana.edu% cat ChatClient.java import java.rmi.*; import java.rmi.server.*; import java.io.*; public class ChatClient implements ClientExports { String name; public ChatClient(String name) throws RemoteException { System.out.println("Starting up client..."); this.name = name; } public void update(String message) { System.out.print(message); } public static void main(String[] args) { try { ServerExports serverFarAway = (ServerExports) Naming.lookup( "rmi://" + args[1] + ".cs.indiana.edu:" + args[2] + "/Dirac"); ChatClient thisGuyHere = new ChatClient(args[0]); UnicastRemoteObject.exportObject(thisGuyHere); serverFarAway.register(thisGuyHere); serverFarAway.broadcast("***(" + thisGuyHere.name + ")*** has just connected.\n"); thisGuyHere.talkAndRelayTo(serverFarAway); } catch (Exception e) { System.out.println("Client: error in main..." + e); } } public void talkAndRelayTo(ServerExports remoteServer) { try { InputStreamReader reader = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(reader); String line = br.readLine(); while (! line.equals("quit")) { System.out.println("You typed: " + line); remoteServer.broadcast(name + "> " + line + "\n"); line = br.readLine(); } } catch (Exception e) { System.out.println("Client: error in talk..." + e); } } } burrowww.cs.indiana.edu% cat ChatServer.java import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; import java.util.*; public class ChatServer extends UnicastRemoteObject implements ServerExports { Vector chatters = new Vector(); public ChatServer() throws RemoteException { System.out.println("Server being initialized..."); } public void register(ClientExports remote) throws RemoteException { chatters.addElement(remote); } public void broadcast(String message) throws RemoteException { for (int i = 0; i < chatters.size(); i++) { try { ((ClientExports)(chatters.elementAt(i))).update(message); } catch(Exception e) { System.out.println("Client unavailable..."); } } } public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); try { ChatServer pam = new ChatServer(); Registry catalogue = LocateRegistry.createRegistry(Integer.parseInt(args[0])); catalogue.bind("Dirac", pam); System.out.println("Server is ready..."); } catch (Exception e) { System.out.println("Server error: " + e + "..."); } } } burrowww.cs.indiana.edu% javac *.java burrowww.cs.indiana.edu% ls -ld *.java -rw-r--r-- 1 dgerman faculty 1469 Nov 13 14:17 ChatClient.java -rw-r--r-- 1 dgerman faculty 1138 Nov 13 16:08 ChatServer.java -rw-r--r-- 1 dgerman faculty 135 Nov 13 16:07 ClientExports.java -rw-r--r-- 1 dgerman faculty 208 Nov 13 16:08 ServerExports.java burrowww.cs.indiana.edu% rmic ChatServer burrowww.cs.indiana.edu% rmic ChatClient burrowww.cs.indiana.edu% exit burrowww.cs.indiana.edu%
We'll test it this way.