# RMI - dynamisch Code nachladen



## sheddy (10. Jan 2009)

Moin, 

ich habe ein Problem mit dem dynamischen Nachlden von Code.

Mein Projekt sieht wie folgt aus:

Klassen:

Interface
Server
Client

Auf dem Server läuft die registry und ein Web-Server, der das Interface als JAR-File bereit stellt.
Auf dem Client sind folgende Klassen:

Client
Interface

Auf dem Server sind diese:

Server
Interface

So weit funktioniert es. Aber das Interface sollte bei RMI ja nicht auf dem Client UND dem Server liegen, sondern bei bedarf nachgeladen werden, deshalb der Web-Server.

Wenn ich aber, die Interface-Klasse auf dem Client lösche, kann ich den Clent nicht mehr starten, da beim "lookup" ja das Interface schon benötigt wird.
Hier ein Codeausschnitt:


```
public class Client {
	public static void main(String[] args) {
		
		
		
		System.getProperties().put("java.rmi.server.codebase", "http://192.168.0.24:8080/IShop/myInterface.jar");
		System.getProperties().put("java.security.policy", "shop.policy");		
		
		System.setSecurityManager(new SecurityManager());		
		
		try{
			
			
			myInterface stub = (myInterface) Naming.lookup("rmi://192.168.0.24:3000/shop5");

		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}
```

Diese zeile

```
myInterface stub = (myInterface) Naming.lookup("rmi://192.168.0.24:3000/shop5");
```
löst dann einen Fehler aus, weil er die Klasse nicht mehr findet, die ja dynamisch nachgeladen werden soll.

Was mache ich da falsch?!

Ich kann schlecht immer das Interface auf dem Server UND dem Client verteilen. Wenn es mehrere Clients werden, muss das Interface immer wieder erneut verteilt werden.

Vielen Dank für eure Hilfe

Gruß
sdy


----------



## SlaterB (11. Jan 2009)

nur implementierende Klassen werden dynamisch nachgeladen,

wenn der Server vom Interface X ist und eine Liste von Objekten des Interface Y oder der Klasse Z zum Client senden kann,
dann muss der Client zwingend X und Y oder Z als ganz normale Interface/ Klassen kennen,

nur wenn der Server nun Objekte einer unbekannten Klassen U implements X oder U extends Z sendet,
dann kann der Client darauf ja überhaupt nicht reagieren, diese Klasse muss dynamisch nachgeladen werden

---

was du möchtest scheint mir ausgeschlossen,
X und Y sind sind so elementar für das Client-Programm wie die Java-API (String, ArrayList) und die sonstigen Client-spezifischen Klassen 

wenn 
myInterface stub = (myInterface) Naming.lookup("rmi://192.168.0.24:3000/shop5"); 
ausgeführt wird,
dann kommt die lookup()-Methode dran, die in tausenden Arbeitsschritten benötigte und vorhandene Klassen 
prüfen kann, zusätzliche Verbindungen zum Server öffnet usw.

aber um die Client-Klasse überhaupt bis zu diesem Punkt hin auszufühen,
muss erstmal die Java-VM diese Klasse verstehen,
und die hat nun keine Möglichkeit, irgendwelche Klassen nachzuladen,
wenn das so direkt ginge, dann bräuchte es ja keine RMI-API


-------

Klassen groß schreiben!


----------



## sheddy (11. Jan 2009)

> wenn der Server vom Interface X ist und eine Liste von Objekten des Interface Y oder der Klasse Z zum Client senden kann,
> dann muss der Client zwingend X und Y oder Z als ganz normale Interface/ Klassen kennen,
> 
> nur wenn der Server nun Objekte einer unbekannten Klassen U implements X oder U extends Z sendet,
> dann kann der Client darauf ja überhaupt nicht reagieren, diese Klasse muss dynamisch nachgeladen werden



Klingt beides einleuchtend, aber widerspricht sich doch, oder?! Das untere will ich ja realisieren. Der Client braucht aber das Interface, um überhaupt den Stub zu holen und darüber kann er dann dann andere Klassen/ Interfaces laden?


----------



## SlaterB (11. Jan 2009)

wo genau liegt der Widerspruch?

natürlich ist es technisch gesehen bestimmt irgendwie möglich,
auch X und Y vom Server zu laden,
z.B. mit vorher ausgeführten Code loadClassFromServer("X");
aber mit RMI hat das dann nix zu tun


----------



## sheddy (11. Jan 2009)

Deshalb habe ich ja die VM Parameter, in denen ich angebe, wo die codebase liegt. dazu ist die anweisung doch da?!


Anscheinend ist es ja möglich Code dynamisch nachzuladen: Dynamic code downloading using RMI

Schön und gut, aber wie soll man denn die neue Klasse nutzen, die man vorher ja im Code verwenden muss. Also schon bei der Entwicklung verwendet haben muss, um Objekte davon verarbeiten zu können?!   ???:L


----------



## SlaterB (11. Jan 2009)

codbase ist dafür da, dass der ganz normale Java-Code in  Naming.lookup() diesen VM-Parameter abfragt 
und dann mit einer Vielzahl von Java-Befehlen die Klassen nachlädt, 
das ist kein Teil der VM oder gar der Java-Sprache sondern schlichte Open Source-Programmierung wie du sie auch selber mit if/ else, Sockets usw zusammenbasteln könntest

das geht aber nur mit ordentlich kompilieren Code zu dem alle benötigten Libraries vorhanden sind

> Also schon bei der Entwicklung verwendet haben muss, um Objekte davon verarbeiten zu können?!

Java setzt auf Polymorphie auf,
zur Entwicklung benutzt du nur das Interface, dies muss dann auch als echte Java-Klasse vorhanden sein,
die Objekte der unbekannten nachgeladenen Klassen werden nur über das Interface angesprochen und Java leitet die Aufrufe intern an die richtige Methoden weiter


----------

