# Remote Method Invocation

Remote Method Invocation (RMI, deutsch etwa „Aufruf entfernter Methoden“), gelegentlich auch als Methodenfernaufruf bezeichnet, ist der Aufruf einer Methode eines entfernten Java-Objekts und realisiert die Java-eigene Art des Remote Procedure Call. „Entfernt“ bedeutet dabei, dass sich das Objekt in einer anderen Java Virtual Machine befinden kann, die ihrerseits auf einem entfernten Rechner oder auf dem lokalen Rechner laufen kann. Dabei sieht der Aufruf für das aufrufende Objekt (bzw. dessen Programmierer) genauso aus wie ein lokaler Aufruf, es müssen jedoch besondere Ausnahmen (Exceptions) abgefangen werden, die zum Beispiel einen Verbindungsabbruch signalisieren können.
Auf der Client-Seite kümmert sich der sogenannte Stub um den Netzwerktransport. Der Stub muss entweder lokal oder über das Netz für den Client verfügbar sein. Vor dem Erscheinen der Java 2 Standard Edition (J2SE) in Version 1.5.0 war der Stub eine mit dem RMI-Compiler rmic erzeugte Klasse. Ab der Version 1.5 ist es nicht mehr notwendig, den RMI-Compiler rmic aufzurufen. Das Erstellen des Stubs wird von der Java Virtual Machine übernommen.
Entfernte Objekte können zwar auch von einem bereits im Programm bekannten entfernten Objekt bereitgestellt werden, für die erste Verbindungsaufnahme werden aber die Adresse des Servers und ein Bezeichner (ein RMI-URL) benötigt. Für den Bezeichner liefert ein Namensdienst auf dem Server eine Referenz auf das entfernte Objekt zurück. Damit dies funktioniert, muss sich das entfernte Objekt im Server zuvor unter diesem Namen beim Namensdienst registriert haben. Der RMI-Namensdienst wird über statische Methoden der Klasse java.rmi.Naming angesprochen. Der Namensdienst ist als eigenständiges Programm implementiert und wird RMI Registry genannt.

## Kommunikationsprotokoll

RMI bezeichnet außerdem ein auf TCP/IP und JRMP basierendes Kommunikationsprotokoll, das für entfernte Aufrufe zwischen Java-Objekten verwendet wird, und eine Java-Standard-Klassenbibliothek, mit der diese Aufrufe realisiert werden können. Diese Klassenbibliothek ist Teil der J2SE. Alternativ kann auch IIOP als Kommunikationsprotokoll eingesetzt werden. Für RMI sind zwei Ports reserviert. Port 1099 ist für die RMI-Registry reserviert, also den Namensdienst. Port 1098 ist für den Activator reserviert.

## Komponenten
### Remote Interface

    ist ein Subinterface von java.rmi.Remote und beschreibt die Funktionen, die auf dem Server zur Verfügung stehen. Damit definiert es das Verhalten des entfernten Objekts (ohne dieses zu implementieren). Jede abstrakte Methode des Remote Interfaces muss in ihrer throws-Klausel eine RemoteException deklarieren.

### Remote Object

    stellt das entfernte Objekt dar und liegt auf dem Server. Es implementiert das Remote Interface und das Verhalten der für die Clients zur Verfügung stehenden entfernten Methoden. Vom Server können eine oder mehrere Instanzen des Remote-Objekts erstellt werden. Ein Remote Object muss von UnicastRemoteObject abgeleitet sein. Es muss mindestens ein Konstruktor zur Verfügung gestellt werden, der in seiner throws-Klausel eine geprüfte Ausnahme vom Typ RemoteException deklariert, da der parameterlose Konstruktor von UnicastRemoteObject in seiner throws-Klausel diese geprüfte Ausnahme ebenfalls deklariert. Das Remote Object kann Methoden implementieren, die nicht im Remote Interface auftauchen – diese können dann aber nur lokal aufgerufen werden.

### Remote Reference

    ist eine Referenz auf Remote Objects. Die Clients bekommen die Remote Reference von der RMI Registry.

## Ablauf

* Der Server registriert ein Remote Object bei der RMI-Registry unter einem eindeutigen Namen.
* Der Client sieht bei der RMI-Registry unter diesem Namen nach und bekommt eine Objektreferenz, die seinem Remote Interface entsprechen muss.
* Der Client ruft eine Methode aus der Objektreferenz auf (dass diese Methode existiert, wird durch das Remote Interface garantiert). Dabei kann ein Objekt einer Klasse X übergeben werden, die der JVM des Servers bisher nicht bekannt ist (das ist möglich, wenn X ein dem Server bekanntes Interface implementiert). In diesem Fall lädt die Server-JVM die Klasse X dynamisch nach, beispielsweise vom Webserver des Client.
* Die Server-JVM führt die Methode auf dem Remote Object aus, wobei evtl. dynamisch geladener Fremdcode benutzt wird (z. B. Methoden von X), der im Allgemeinen Sicherheitsrestriktionen unterliegt. Dem Client werden die Rückgabewerte dieses Aufrufes gesendet, oder der Client bekommt eine Fehlermeldung (z. B. bei einem Verbindungsabbruch).

## Activation

Als Ergänzung von RMI steht die sogenannte Activation („Aktivierung“) zur Verfügung. Ähnlich der RMI-Registry ist auch dies eine zentrale Anlaufstelle für RMI-Clients. Jedoch kann der Activator auch RMI-Server-Objekte erzeugen und neue Virtuelle Maschinen starten.