Lab

0

Middleware Platforms

Introduction to Java RMI


Systems Architecture Group

Ablieferungstermin und erreichbare Punktzahl für diese Aufgabe, sowie Voraussetzungen für die Prüfungszulassung entnehmen Sie bitte http://sar.informatik.hu-berlin.de.

In dieser Aufgabe soll das Beispiel zu Java RMI aus der Vorlesung praktisch umgesetzt werden. Hintergrund der Aufgabe ist der Aktienmarkt. Die zu entwickelnde Anwendung gliedert sich in zwei Teile: einen Client und einen Server.

Teil A – Server

Der Server stellt nur eine Funktion zur Verfügung: die Ermittlung des aktuellen Kurses zu einer gegebenen Aktie (identifiziert durch deren Symbol).

Erster Schritt in der Entwicklung der Server-Anwendung ist die Definition eines Interfaces für das entfernte Objekt entsprechend der Java RMI Konventionen:

  • Das Interface muss von java.rmi.Remote abgeleitet sein.
  • Es führt alle Methoden auf, die entfernt aufrufbar sein sollen.
  • Alle Methoden müssen mit throws java.rmi.RemoteException deklariert sein.
  • Spezielle Semantik in der Parameterübergabe.

Das folgende Interface ist eine mögliche Variante und soll im Weiteren verwendet werden.

package simpleStocks;
 
import java.rmi.Remote;
import java.rmi.RemoteException;
 
public interface StockMarket extends Remote {
      float get_price( String symbol ) throws RemoteException;
}

Nächster Schritt ist die Implementierung der entfernten Methoden. Dazu wird eine Klasse StockMarketImpl verwendet, die von der Klasse UnicastRemoteObject erbt und das Interface StockMarket implementiert. Für das gewählte Beispiel ist nur die entfernte Methode get_price zu realisieren, die zu einem Symbol den entsprechenden Aktienkurs zurückliefert. Eine mögliche Implementierung könnte wie folgt aussehen.

package simpleStocks;
 
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
 
public class StockMarketImpl
extends UnicastRemoteObject
implements StockMarket {
     
      public StockMarketImpl() throws RemoteException {
            super();
      }
     
      public float get_price( String symbol ) throws RemoteException {
            float price = 0;
            for( int i = 0; i < symbol.length(); i++ ){
                  price += (int) symbol.charAt( i );
            }
            price /= 5;
            return price;
      }
}

Im Anschluss daran kann mit dem Compiler rmic der benötigte Stub-Code erzeugt werden:

 $ rmic -keep -classpath .  simpleStocks.StockMarketImpl

Als letzten Schritt für der Implementierung des Servers wird ein Objekt der Klasse StockMarketImpl erzeugt und im Namensdienst registriert:

package simpleStocks;
 
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
 
public class StockMarketServer {
     
      public static void main(String[] args) throws Exception {
            StockMarketImpl stockMarketImpl = new StockMarketImpl();
            try {
                  Naming.rebind( "NASDAQ", stockMarketImpl );
            }
      catch( Exception e ) {
                  System.out.println( e );
      }
      }
}

Zum Starten des Servers muss zuvor die RMI Registry gestartet werden. Das kann wie folgt geschehen:

 $ rmiregistry

Nun kann der Server selbst gestartet werden:

 $ java simpleStocks.StockMarketServer

 

Teil B – Client

Das soeben geschaffene, verteilte Objekt kann nun in Client-Anwendungen benutzt werden. Dazu wird eine Referenz des verteilten Objekts über den Namensdienst bezogen und in den Typ des zuvor entwickelten Interfaces umgewandelt. Nun kann mit der Referenz wie mit einem lokalen Objekt gearbeitet werden:

package simpleStocks;
 
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
 
public class StockMarketClient {
 
      public static void main(String[] args) throws Exception {
            StockMarket market =
                  (StockMarket)Naming.lookup("rmi://localhost/NASDAQ");
            System.out.println( "The price of MY COMPANY is "
                        + market.get_price("MY_COMPANY") );
      }
}

Abgabe

Begründen Sie die von Ihnen getroffenen Design-Entscheidungen und beschreiben Sie aufgetretene Besonderheiten und Probleme. Benutzen Sie dafür eine HTML Datei mit dem Namen index.html. Abzugeben sind weiterhin die Quelltexte der Lösung und ein Ant Skript mit dem Namen build.xml, das die Quellen mit den gängigen Werkzeugen automatisiert übersetzt. Bitte reichen Sie die geforderten Dateien in ein ZIP Archiv gepackt ein. 

Testen Sie Ihre Lösung mit der Unit-Test-Bibliothek jUnit (www.junit.org). Schreiben Sie dazu eine Klasse StockQuoterTest, die die Anwendung anhand von verschiedenen Unit-Tests testet. Sie können als Grundlage das folgende Fragment verwenden. Ergänzen Sie das Ant Skript um ein Target test, dass die von Ihnen entworfenen Testfälle automatisiert durchführt.

package simpleStocks;
import junit.framework.TestCase;
 
 
public class StockMarketTest extends TestCase {
  StockMarket _market = null;
 
  public static void main(String[] args) {
    junit.textui.TestRunner.run(StockMarketTest.class);
  }
 
  public StockMarketTest(String name) {
    super(name);
  }
 
  protected void setUp() throws Exception {
    //_market = (StockMarket)Naming.lookup(...);
  }
 
  protected void tearDown() throws Exception {
    _market = null;
  }
 
  public void test1() throws Exception {
  }
}

Hinweise

Ressourcen


Legal disclaimer. © 2004 Humboldt University Berlin, Computer Science Department, Systems Architecture Group.  Mail to: jpr@informatik.hu-berlin.de. Last modified: July 13, 2005

Legal disclaimer. .  © 2024 Humboldt-Universität zu Berlin, Computer Science Department, Systems Architecture Group.Contact: sar@informatik.hu-berlin.de .