# RMI - (RemoteException occurred in server thread)



## JavaRMIler (31. Jan 2006)

Hallo,

ich habe noch nicht lange mit Java zu tun - dies vorab  Dennoch habe ich mich mal an RMI getraut. Dabei bin ich dem RMI Kapitel aus dem Buch "Java ist auch eine Insel" gefolgt. 

Bei Google konnte ich leider keine Infos finden, welche mein Problem lösen...

Aktueller Status:

* Ich habe 3 Dateien. (Adder.java, AdderImpl.java und Server.java).
* rmiregistry.exe ist schon gestartet und wartet...

Das Serverprogramm kompiliert brav - lässt sich allerdings nicht starten... 

$ java Server
Exception in thread "main" java.lang.NoClassDefFoundError: Server

Was dieser Fehler bedeutet ist mir schon klar - aber ich sehe den eigentlichen Fehler nicht (Code folgt später).

Starte ich das Programm via Eclipse kommt folgendes:


```
Jan 31, 2006 6:10:01 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.0.148: [192.168.0.148: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Exception in thread "main" java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
	java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: Adder
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:385)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
	at sun.rmi.transport.Transport$1.run(Transport.java:153)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
	at java.lang.Thread.run(Thread.java:595)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
	at sun.rmi.server.UnicastRef.invoke(Unknown Source)
	at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
	at Server.main(Server.java:15)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: Adder
	at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:375)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
	at sun.rmi.transport.Transport$1.run(Transport.java:153)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
	at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.ClassNotFoundException: Adder
	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:242)
	at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:707)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:651)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:588)
	at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
	at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
	at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
	at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1457)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
	... 9 more
Jan 31, 2006 6:10:01 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(2)-192.168.0.148: [192.168.0.148: sun.rmi.transport.DGCImpl[0:0:0, 2]: void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean)]
```


Und nun der Code der drei Dateien:

Adder.java


```
//package com.javatutor.insel.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Adder extends Remote
{
  public int add( int x, int y ) throws RemoteException;
}
```


AdderImpl.java


```
//package com.javatutor.insel.rmi;
import java.rmi.RemoteException;

public class AdderImpl implements Adder {

	public int add(int x, int y) throws RemoteException {
		// TODO Auto-generated method stub
		return x+y;
	}

}
```


Server.java

```
//package com.javatutor.insel.rmi;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteServer;
import java.rmi.server.UnicastRemoteObject;

public class Server
{
  public static void main( String[] args ) throws Exception
  {
    AdderImpl adder = new AdderImpl();
    Adder stub = (Adder) UnicastRemoteObject.exportObject( adder, 0 );
    RemoteServer.setLog( System.out );
    Registry registry = LocateRegistry.getRegistry();
    registry.rebind( "Adder", stub );
    System.out.println( "Adder angemeldet" );
  }
}
```

Für jeden Tipp bin ich äußerst dankbar. 


[/code]


----------



## JavaRMIler (31. Jan 2006)

neuster Stand: 


```
Jan 31, 2006 10:12:23 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.0.148: [192.168.0.148: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Exception in thread "main" java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
	java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: Adder
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:385)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
	at sun.rmi.transport.Transport$1.run(Transport.java:153)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
	at java.lang.Thread.run(Thread.java:595)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
	at sun.rmi.server.UnicastRef.invoke(Unknown Source)
	at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
	at Server.main(Server.java:15)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: Adder
	at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:375)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
	at sun.rmi.transport.Transport$1.run(Transport.java:153)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
	at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.ClassNotFoundException: Adder
	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:242)
	at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:707)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:651)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:588)
	at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
	at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
	at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
	at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1457)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
	... 9 more
Jan 31, 2006 10:12:32 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(2)-192.168.0.148: [192.168.0.148: sun.rmi.transport.DGCImpl[0:0:0, 2]: void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean)]
```


----------



## EagleEye (31. Jan 2006)

Hauptinterface 

```
import java.rmi.*;
import java.io.*;

public interface DateiEa extends Remote
{
  final int WRITE = 0;		// Betriebsart Schreiben
  final int READ = 1;		// Betriebsart Lesen
  final int MAX_BUF = 500;	// maximale Blocklaenge

 /**
  * Oeffenen einer Datei zum Lesen oder Schreiben
  * Parameter: name - Name der Datei
  *	       mode = WRITE - Schreiben (FileOutputStream)
  *            mode = READ  - Lesen (FileInputStream)
  */
  public void open(String name, int mode) throws RemoteException, IOException;


 /**
  * Lesen eines Blockes aus einer Datei
  * Returns: Bytefeld mit gelesenen Daten 
  *             (Laenge des Feldes entspricht Anzahl der gelesenen Bytes !)
  *	     null - Ende der Datei
  */
  public byte[] blockLesen() throws RemoteException, IOException;


 /**
  * Schreiben eines Blockes in eine Datei
  * Es wird der gesamte Puffer geschrieben.
  * Parameter: buf - Puffer mit Daten
  */
  public void blockSchreiben(byte[] buf) throws RemoteException, IOException;


 /**
  * Schliessen der geoeffneten Datei (des Streams)
  */
  public void close() throws RemoteException, IOException;
}
```
Client

```
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import labor4.a.lokaleDateiEa;
import labor4.a.lokaleDateiEaImpl;

/**
 * Created on 02.01.2006
 */

/**
 * @author Eagle Eye
 * 
 */
public class RMIClient
{
  public static void main(String[] args)
  {
    try
    {
      if(args.length==2)
      {
        DateiEa von = (DateiEa)Naming.lookup("rmi://localhost/kopieren");
        lokaleDateiEaImpl nach = new lokaleDateiEaImpl();
        byte[] puffer;

        try
        {
          von.open(args[0],lokaleDateiEa.READ);
          nach.open(args[1],lokaleDateiEa.WRITE);
          while((puffer = von.blockLesen())!=null)
          {
            System.out.println("gelesen: "+puffer.length);
            nach.blockSchreiben(puffer);
            System.out.println("geschrieben: "+puffer.length);
          }
          von.close();
          nach.close();
        }
        catch(Exception e)
        {
          System.out.println("Datei: "+e.getMessage());
          e.printStackTrace();
        }
      }
      else
        System.out.println("Aufruf: java lokaleDateiEaImpl vonDatei nachDatei");
    }
    catch(MalformedURLException ex)
    {
      // TODO Auto-generated catch block
      ex.printStackTrace();
    }
    catch(RemoteException ex)
    {
      // TODO Auto-generated catch block
      ex.printStackTrace();
    }
    catch(NotBoundException ex)
    {
      // TODO Auto-generated catch block
      ex.printStackTrace();
    }
  }
}
```
Server

```
/**
 * lokale Variante fuer einen "Datei-Kopierer"
 * 
 * Anmerkungen:
 * - die Konstanten des Interfaces koennen auch ohne den Namen des
 *   Interfaces vor den Konstanten ("lokaleDateiEa.") benutzt werden
 */

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;



public class RMIServer extends UnicastRemoteObject implements DateiEa
{
  private BufferedInputStream in;
  private BufferedOutputStream out;
  private byte[] puffer = new byte[lokaleDateiEa.MAX_BUF];

  public RMIServer() throws RemoteException
  {}

  public void open(String name,int mode) throws IOException
  {
    if(mode==lokaleDateiEa.READ)
      in = new BufferedInputStream(new FileInputStream(name));
    if(mode==lokaleDateiEa.WRITE)
      out = new BufferedOutputStream(new FileOutputStream(name));
  }

  public byte[] blockLesen() throws IOException
  {
    int length = in.read(puffer);
    if(length==-1)
      return null;
    if(length!=lokaleDateiEa.MAX_BUF)
    {
      byte[] buf = new byte[length];
      for(int i = 0;i!=length;i++)
        buf[i] = puffer[i];
      return buf;
    }
    return puffer;
  }

  public void blockSchreiben(byte[] buf) throws IOException
  {
    out.write(buf);
  }

  public void close() throws IOException
  {
    if(in!=null)
      in.close();
    if(out!=null)
      out.close();
  }

  public static void main(String[] args)
  {
    System.setSecurityManager(new RMISecurityManager());
    try
    {
      RMIServer impl = new RMIServer();
      Naming.rebind("kopieren",impl);
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  }
}
```
Klasse vom Client

```
package labor4.a;

/**
 * lokale Variante fuer einen "Datei-Kopierer"
 * 
 * Anmerkungen:
 * - die Konstanten des Interfaces koennen auch ohne den Namen des
 *   Interfaces vor den Konstanten ("lokaleDateiEa.") benutzt werden
 */

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class lokaleDateiEaImpl implements lokaleDateiEa
{
  private BufferedInputStream in;
  private BufferedOutputStream out;
  private byte[] puffer = new byte[lokaleDateiEa.MAX_BUF];

  public lokaleDateiEaImpl()
  {}

  public void open(String name,int mode) throws IOException
  {
    if(mode==lokaleDateiEa.READ)
      in = new BufferedInputStream(new FileInputStream(name));
    if(mode==lokaleDateiEa.WRITE)
      out = new BufferedOutputStream(new FileOutputStream(name));
  }

  public byte[] blockLesen() throws IOException
  {
    int length = in.read(puffer);
    if(length==-1)
      return null;
    if(length!=lokaleDateiEa.MAX_BUF)
    {
      byte[] buf = new byte[length];
      for(int i = 0;i!=length;i++)
        buf[i] = puffer[i];
      return buf;
    }
    return puffer;
  }

  public void blockSchreiben(byte[] buf) throws IOException
  {
    out.write(buf);
  }

  public void close() throws IOException
  {
    if(in!=null)
      in.close();
    if(out!=null)
      out.close();
  }

  public static void main(String[] args)
  {
    if(args.length==2)
    {
      lokaleDateiEaImpl von = new lokaleDateiEaImpl();
      lokaleDateiEaImpl nach = new lokaleDateiEaImpl();
      byte[] puffer;

      try
      {
        von.open(args[0],lokaleDateiEa.READ);
        nach.open(args[1],lokaleDateiEa.WRITE);
        while((puffer = von.blockLesen())!=null)
        {
          System.out.println("gelesen: "+puffer.length);
          nach.blockSchreiben(puffer);
          System.out.println("geschrieben: "+puffer.length);
        }
        von.close();
        nach.close();
      }
      catch(Exception e)
      {
        System.out.println("Datei: "+e.getMessage());
        e.printStackTrace();
      }
    }
    else
      System.out.println("Aufruf: java lokaleDateiEaImpl vonDatei nachDatei");
  }
}
```
Interface vom Client

```
package labor4.a;

/**
 * lokale Schnittstelle fuer Dateizugriffsprozeduren
 * 
 */


import java.io.*;

public interface lokaleDateiEa
{
  final int WRITE = 0;		// Betriebsart Schreiben
  final int READ = 1;		// Betriebsart Lesen
  final int MAX_BUF = 500;	// maximale Blocklaenge

 /**
  * Oeffenen einer Datei zum Lesen oder Schreiben
  * Parameter: name - Name der Datei
  *	       mode = WRITE - Schreiben (FileOutputStream)
  *            mode = READ  - Lesen (FileInputStream)
  */
  public void open(String name, int mode) throws IOException;


 /**
  * Lesen eines Blockes aus einer Datei
  * Returns: Bytefeld mit gelesenen Daten 
  *          (Laenge des Feldes entspricht Anzahl der gelesenen Bytes !)
  *	     null - Ende der Datei
  */
  public byte[] blockLesen() throws IOException;


 /**
  * Schreiben eines Blockes in eine Datei
  * Parameter: buf - Puffer mit Daten
  */
  public void blockSchreiben(byte[] buf) throws IOException;


 /**
  * Schliessen der geoeffneten Datei (des Streams)
  */
  public void close() throws IOException;
}
```
Die Klasse und das Interface vom Clienten kann man auch anders schreiben war bei uns nur so weils Teil einer anderen Aufgabe war


----------

