Java Q&A
by Govind Seshadri 


Example 1:

javac -d . QClientInterface.java 
javac -d . QServerInterface.java 
javac -d . QuoteServer.java 
javac -d . QuoteApplet.java           

Example 2:

rmic -d . mypackage.rmiexamples.QuoteServer
rmic -d . mypackage.rmiexamples.QuoteApplet


Listing One
/** Defines the methods available to the client for remote invocation */
package mypackage.rmiexamples;
public interface QServerInterface extends java.rmi.Remote {
    public  void addQuote(String quote) throws java.rmi.RemoteException;
    public  void setQClientInterface(QClientInterface c) 
                                         throws java.rmi.RemoteException;
}


Listing Two
/** Defines methods available to server for remote invocation as callbacks */
package mypackage.rmiexamples;
public interface QClientInterface extends java.rmi.Remote {
        public void refreshClient(String q) throws java.rmi.RemoteException;
}


Listing Three
package mypackage.rmiexamples;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import mypackage.rmiexamples.QClientInterface;
import mypackage.rmiexamples.QServerInterface;
import java.util.*;
import java.rmi.registry.LocateRegistry;

public class QuoteServer extends UnicastRemoteObject 
                                      implements QServerInterface, Runnable {
    private Vector clientele; //tracks all connected clients
    private QClientInterface myQClientInterface; 
    private Vector quoteList; //maintains updatable list of quotes
    private QClientInterface myClientObj;
    private Thread clientThread=null;
    private static int counter=0;

    public QuoteServer ()  throws java.rmi.RemoteException {
       super();
       // create and initialize the quote list 
       quoteList = new Vector();
       quoteList.addElement("Climb mountains to see lowlands");
       quoteList.addElement("If you want the rainbow, put up with the rain");
       quoteList.addElement("Smooth seas do not make skilful sailors");
       clientele = new Vector();
    }
    public  void setQClientInterface(QClientInterface c) 
                                                 throws RemoteException {
        synchronized (clientele) {
            clientele.addElement(c);
        }
       if (clientThread == null) {
            clientThread = new Thread(this, "clientThread");
            clientThread.start();
        }
    }
    private void doIt() {
        synchronized (clientele) {
            Vector backup = (Vector) clientele.clone();
            int seed;
            while ((seed = new Random().nextInt()) <=0) ;
                seed = seed % quoteList.size();
                String data = quoteList.elementAt(seed)+ ": "+ ++counter;
                for (int i=0; i < clientele.size(); i++) {
                    myClientObj = (QClientInterface) clientele.elementAt(i);
                    try {
                        //update the client asynchronously via callback
                        myClientObj.refreshClient((String) data );
                    } catch (RemoteException e) {
                        System.out.println("client must have disconnected!");
                        //get rid of remote reference for disconnected client
                        backup.removeElement(myClientObj);
                        if (backup.size() <= 0) {
                            //no more clients- so stop server thread
                            clientele = (Vector) backup.clone();
                            Thread dummy = clientThread;
                            clientThread = null;
                            dummy.stop();
                        }
                    }
            }
            clientele = (Vector) backup.clone();
        } //end syncronization on clientele
    }
    public void run() 
    {
        while (true) {
            try {
                //sleep for a second
                Thread.currentThread().sleep(1000);
            } catch (Exception e) { 
                                    }
            doIt();
        }
    }   
    public void addQuote(String quote) throws RemoteException {
        synchronized (quoteList) {
            //update quote list
            quoteList.addElement(quote);
        }
    }
    public static void main(String[] args) {
        System.setSecurityManager(new RMISecurityManager());
        try {
            System.out.println("QuoteServer.main: creating registry");  
            LocateRegistry.createRegistry(1099);
            System.out.println("QuoteServer.main: creating server");
            QuoteServer myQuoteServer=new QuoteServer();
            System.out.println("QuoteServer.main: binding server ");
            Naming.rebind("/QuoteServer", myQuoteServer);
            System.out.println("QuoteServer bound in registry");
         } catch (Exception e) {
            System.out.println("Exception on binding QuoteServer");
            System.out.println(e.toString());
          }
    }
}


Listing Four
package mypackage.rmiexamples;

import mypackage.rmiexamples.QServerInterface;
import mypackage.rmiexamples.QClientInterface;
import java.rmi.*;
import java.rmi.server.*;
import java.util.Random;
import java.awt.*;
import java.applet.*;
public class QuoteApplet extends Applet implements QClientInterface {
public QServerInterface  srvQuote=null;

    //the client uses jdk1.1 event handling mechanism
    void sendQuote_Clicked(java.awt.event.ActionEvent event) {
        try {
            //update the remote server object with a new quote
            srvQuote.addQuote((String)myQuote.getText());
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
    public void init() {
    super.init();
        try {
            //by exporting the client object, turn it into a
            //remote object 
            UnicastRemoteObject.exportObject(this);
        } catch (Exception e) {
            System.out.println("Could not export client remote object");
            System.out.println(e);
              }
    try {
        //obtain the remote server object's reference by interrogating the
       //rmi registry
            srvQuote = (QServerInterface) 
                Naming.lookup("//"+getCodeBase().getHost()+"/QuoteServer");
           srvQuote.setQClientInterface(this);
    } catch (Exception e) {
        System.out.println("Could not set client interface at server");
       System.out.println(e.toString());
    }
}
    public void addNotify() {

        //don't worry about the specifics of the
               //following code. All it does is create a GUI
              //for the rmi client
                   super.addNotify();
        setLayout(null);
        resize(1016,565);
        label1 = new java.awt.Label("Input Quote:");
        label1.reshape(21,24,72,21);
        add(label1);
        myQuote = new java.awt.TextField();
        myQuote.reshape(104,24,242,21);
        add(myQuote);
        sendQuote = new java.awt.Button("Send");
        sendQuote.reshape(357,24,48,21);
        add(sendQuote);
        quoteList = new java.awt.TextArea();
        add(quoteList);
        quoteList.reshape(36,60,371,125);

        //register listners
        Action lAction = new Action();
        sendQuote.addActionListener(lAction);
    }
    java.awt.Label label1;
    java.awt.TextField myQuote;
    java.awt.Button sendQuote;
    java.awt.TextArea quoteList;
public void refreshClient(String q) throws java.rmi.RemoteException {
    //this is the callback method implementation
        quoteList.append(q+"\n");
}
class Action implements java.awt.event.ActionListener {
        public void actionPerformed(java.awt.event.ActionEvent event) {
            Object object = event.getSource();
            if (object == sendQuote)
                sendQuote_Clicked(event);
        }
    }
}


