# RMI - Client Zugriff auf Server funktioniert nicht



## tobitobsen82 (1. Mai 2008)

Hallo,

ich arbeite gerade an einer simplen Bankkonten-Anwendung. Es gibt u. a. einen BankClient (Client) und eine Bank (Server). Nebst diesen noch einige Interfaces und Implements zur Verwaltung der Kunden und Konten (Objekte). Das ganze läuft über zwei Swing-Fenster, eins für den Kunden und eins für die Bank. Das Bank-Fenster funktioniert einwandfrei und das Auslesen der Kunden- und Kontendaten bereitet keine Probleme. Der Client kann sich zwar anmelden und der lookup() funktioniert auch, aber sobald ich auf bestehende Konten zugreifen möchte erhalte ich folgende Fehlermeldung:



> java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
> java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: serverPackage.AccountAdmin
> at sun.rmi.server.UnicastRef.invoke(Unknown Source)
> at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
> ...



Leider habe ich dazu bislang keine passende Lösung gefunden.

Nachfolgend noch meine beiden mains (BankClient.java und Bank.java):


```
package clientPackage;

import java.io.IOException;
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import serverPackage.AccountInterface;

public class BankClient {

	public static void main(String[] args) throws NotBoundException, IOException {
		Registry registry = LocateRegistry.getRegistry(); 
		AccountInterface serverObject = (AccountInterface) registry.lookup("AccountAdmin");
		
		ClientGui clientWindow = new ClientGui(serverObject);
		
	}
}
```


```
package serverPackage;

import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Bank {

	public static void main(String[] args) throws IOException {
		Account myBank;
		AccountAdmin myAdmin;
		try {
			LocateRegistry.createRegistry( Registry.REGISTRY_PORT ); 
			
			myBank = new Account();
			Naming.rebind("AccountAdmin", myBank);
			
			myAdmin = new AccountAdmin(); 
			
			Customer customer1 = new Customer("c1", "Hans Günther");
			Account accountC1 = new Account(customer1, "a1", 332.45);
			myAdmin.addAccount(accountC1);
			
			ServerGui serverWindow = new ServerGui(myAdmin);
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

}
```

Danke für eure Hilfe!


----------



## tfa (1. Mai 2008)

AccountAdmin ist nicht Serializable?


----------



## tobitobsen82 (1. Mai 2008)

danke, habs importiert und geht weiter zum nächsten problem. versuch es aber erstma selbst.


----------



## tobitobsen82 (1. Mai 2008)

Tja irgendwie komme ich nicht weiter.

Hab mein Programm nochma etwas umgeschrieben und besser strukturiert, komme aber über den Client einfach nicht an meinen Konten bzw. Kunden ran. Vom Server läufts über dieselbe Klasse (die Impl des Interface für den Client) wunderbar.


```
public class BankClient {

	public static void main(String[] args) throws NotBoundException, IOException {
		
		Registry registry = LocateRegistry.getRegistry(); 
		AccountAdmin serverObject = (AccountAdmin) registry.lookup("AccountAdmin");
		
		ClientGui clientWindow = new ClientGui(serverObject);
		System.out.println(serverObject.getAccounts().size());
	}
}
```

der syso liefert 0, obwohl 6 Accounts angelegt wurden und diese über den Server auch abrufbar sind:


```
package serverPackage;

import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Bank {

	public static void main(String[] args) throws IOException {
		AccountAdmin myAdmin;
		
		try {
			myAdmin = new AccountAdmin();
			
			LocateRegistry.createRegistry( Registry.REGISTRY_PORT );
			Naming.rebind("AccountAdmin", myAdmin); 
			
			Customer customer1 = new Customer("c1", "Hans Günther");
			Account accountC1 = new Account(customer1, "a1", 332.45);
			myAdmin.addAccount(accountC1);
			
			Customer customer2 = new Customer("c2", "Willy Sowieso");
			Account accountC2 = new Account(customer2, "a2", 11.05);
			myAdmin.addAccount(accountC2);
			
			Customer customer3 = new Customer("c3", "Hilde Becker");
			Account accountC3 = new Account(customer3, "a3", 5402.78);
			myAdmin.addAccount(accountC3);
			
			Customer customer4 = new Customer("c4", "Heinz Becker");
			Account accountC4 = new Account(customer4, "a4", 143.12);
			myAdmin.addAccount(accountC4);
			
			Customer customer5 = new Customer("c5", "Angie Merkel");
			Account accountC5 = new Account(customer5, "a5", 76.39);
			myAdmin.addAccount(accountC5);
			
			Customer customer6 = new Customer("c6", "Michael Jackson");
			Account accountC6 = new Account(customer6, "a6", 98720.98);
			myAdmin.addAccount(accountC6);
			
			ServerGui serverWindow = new ServerGui(myAdmin);
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

}
```


----------



## tobitobsen82 (8. Mai 2008)

Nächster Schritt! Da ich die Reihenfolge nicht beachtet hatte, konnte mein "rebind()-Objekt" gar keinen Inhalt haben...das ist nun gelöst.

Allerdings habe ich nun folgendes Problem:

Das Objekt, welches auf der Serverseite erstellt wird, wird an den Client per lookup() als Remote-Objekt übertragen. Der Client hat folglich alle Daten, die das Server-Objekt mit sich gebracht hat. Wenn ich nun auf meinem Client Änderungen an dem (Remote) Objekt durchführe, werden diese zwar auf dem (Remote) Objekt geschrieben, nicht jedoch auf dem Server Objekt.

In meiner konkreten Banken-Anwendung bedeutet das, wenn ein Kunde Geld von seinem "Client-Konto" abhebt, kriegt die Bank (der Server) davon nichts mit. Ungünstig (für die Bank und für mich...)

Bin für jeden Rat dankbar!

Hier ein Ausschnitt aus meinem Client und meinem Server:

Client:

```
package clientPackage;

import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import serverPackage.AccountAdminInterface;

public class BankClient {

	public static void main(String[] args) throws NotBoundException, IOException {
		
		Registry registry = LocateRegistry.getRegistry(); 
		AccountAdminInterface serverObject = (AccountAdminInterface) registry.lookup("AccountAdmin");
		
		ClientGui clientWindow = new ClientGui(serverObject);
		System.out.println(serverObject);
	}
}
```

Server:

```
package serverPackage;

import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Bank {
	
	public static void main(String[] args) throws IOException {
		AccountAdmin myAdmin;
		
		try {
			myAdmin = new AccountAdmin();
			
			Customer customer1 = new Customer("c1", "Hans Günther");
			Account accountC1 = new Account(customer1, "a1", 332.45);
			myAdmin.addAccount(accountC1);
			
                        //.... andere Accounts und Customer werden angelegt
			
			LocateRegistry.createRegistry( Registry.REGISTRY_PORT );
			Naming.rebind("AccountAdmin", myAdmin); 
			
			ServerGui serverWindow = new ServerGui(myAdmin);
			System.out.println(myAdmin);
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

}
```


----------



## tobitobsen82 (8. Mai 2008)

Nachdem ich einige Klassen (AccountAdmin und Account) von UnicastRemoteObject ableiten lasse funktioniert es und beide Seiten (Server/Client) arbeiten auf dem identischen Objekt.


----------

