|
|
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%
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%
Let's see it running.
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%
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;
}
Make a note of this link.
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%
We try again, like last time.
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:
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%
On the client side:
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%
So the file is truly important. Here, however, is another way of doing the same thing.
On the server side (sessions are still intertwined):
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%
On the client side:
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%
So we can bypass the naming convention, but we can't do without doing
something. Now let's try a more sophisticated development.
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 discuss this in class. We'll test it this way.