# Kleines Beispiel zu RMI over IIOP



## Thomas Darimont (24. Mai 2005)

Hallo!

Hier mal wieder ein kleines Beispiel zu RMI. Diesmal bauen wir wieder einen Zeitdienst der nun jedoch IIOP als Kommunikations Protokoll verwendet. 
Unser Anwendungsszenario: Ein Client ruft einen entfernten Dienst per RMI auf und fragt ihn nach der Uhrzeit.

Zu Begin erstellen wir uns zuerst ein Interface namens ITimeService

```
/**
 * 
 */
package de.tutorials.rmioveriiop;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;

/**
 * @author Darimont
 */
public interface ITimeService extends Remote {
	public Date getTime() throws RemoteException;
}
```

Asnchließend erstellen wir uns eine Implementierungsklasse welche den Dienst realsiert.

```
/**
 * 
 */
package de.tutorials.rmioveriiop.impl;

import java.util.Date;

import javax.rmi.PortableRemoteObject;

import de.tutorials.rmioveriiop.ITimeService;

/**
 * @author Darimont
 */
public class TimeServiceImpl extends PortableRemoteObject implements
		ITimeService {

	public TimeServiceImpl() throws Exception {
		super();
	}

	public Date getTime() {
		return new Date();
	}
}
```

Nun kommt noch der Server:

```
/**
 * 
 */
package de.tutorials.rmioveriiop.server;

import javax.naming.Context;
import javax.naming.InitialContext;

import de.tutorials.rmioveriiop.ITimeService;
import de.tutorials.rmioveriiop.impl.TimeServiceImpl;

/**
 * @author Darimont
 *-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory -Djava.naming.provider.url=iiop://localhost:900
 */
public class TimeServer {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		ITimeService service = new TimeServiceImpl();
		Context ctx = new InitialContext();
		ctx.rebind("timeservice", service);
		
		System.out.println("Timeservice ready...");
	}

}
```

... und der Client:

```
/**
 * 
 */
package de.tutorials.rmioveriiop.client;

import javax.naming.Context;
import javax.naming.InitialContext;

import de.tutorials.rmioveriiop.ITimeService;

/**
 * @author Darimont
 */
public class TimeServiceClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		System.out.println("client:");
		Context ctx = new InitialContext();
		
		ITimeService service = (ITimeService) ctx.lookup("timeservice");

		System.out.println(service.getTime());
	}
}
```
dazu. 

Anschließend müssen wir für RMI over IIOP noch die passenden Remote Ties und  Stubs erzeugen.
Dazu gehen wir besipielsweise in die Konsole (...oder per Ant-Task) und geben im Bin Verzeichnis folgende Zeile ein:

```
rmic -iiop de.tutorials.rmioveriiop.impl.TimeServiceImpl
-> Generiert den Remote Tie

und anschließend:
rmic -iiop de.tutorials.rmioveriiop.ITimeService
-> Generiert den Remote Stub
```
Die Option -iiop muss sein, damit die generierten Stubs auch iiop als Kommunikationsprotokoll verwenden.
Der generierte Stub schaut übrigens decompiliert so aus:

```
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov  Date: 24.05.2005 19:37:58
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 

package de.tutorials.rmioveriiop;

import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import java.util.Date;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.ObjectImpl;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.CORBA.portable.ServantObject;

// Referenced classes of package de.tutorials.rmioveriiop:
//            ITimeService

public class _ITimeService_Stub extends Stub
    implements ITimeService
{

    public _ITimeService_Stub()
    {
    }

    public String[] _ids()
    {
        return _type_ids;
    }

    static Class _mthclass$(String s)
    {
        try
        {
            return Class.forName(s);
        }
        catch(ClassNotFoundException classnotfoundexception)
        {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    }

    public Date getTime()
        throws RemoteException
    {
        if(!Util.isLocal(this))
            try
            {
                org.omg.CORBA_2_3.portable.InputStream inputstream = null;
                try
                {
                    Date date1;
                    try
                    {
                        org.omg.CORBA.portable.OutputStream outputstream = _request("_get_time", true);
                        inputstream = (org.omg.CORBA_2_3.portable.InputStream)_invoke(outputstream);
                        Date date = (Date)inputstream.read_value(java.util.Date.class);
                        return date;
                    }
                    catch(ApplicationException applicationexception)
                    {
                        inputstream = (org.omg.CORBA_2_3.portable.InputStream)applicationexception.getInputStream();
                        String s = inputstream.read_string();
                        throw new UnexpectedException(s);
                    }
                    catch(RemarshalException _ex)
                    {
                        date1 = getTime();
                    }
                    return date1;
                }
                finally
                {
                    _releaseReply(inputstream);
                }
            }
            catch(SystemException systemexception)
            {
                throw Util.mapSystemException(systemexception);
            }
        ServantObject servantobject = _servant_preinvoke("_get_time", de.tutorials.rmioveriiop.ITimeService.class);
        if(servantobject == null)
            return getTime();
        try
        {
            Throwable throwable1;
            try
            {
                Date date3 = ((ITimeService)servantobject.servant).getTime();
                Date date2 = (Date)Util.copyObject(date3, _orb());
                return date2;
            }
            catch(Throwable throwable)
            {
                throwable1 = (Throwable)Util.copyObject(throwable, _orb());
            }
            throw Util.wrapException(throwable1);
        }
        finally
        {
            _servant_postinvoke(servantobject);
        }
    }

    private static final String _type_ids[] = {
        "RMI:de.tutorials.rmioveriiop.ITimeService:0000000000000000"
    };

}
```

und der Tie:

```
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov  Date: 24.05.2005 19:38:15
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 

package de.tutorials.rmioveriiop.impl;

import java.rmi.Remote;
import javax.rmi.CORBA.Tie;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Object;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.ResponseHandler;
import org.omg.CORBA.portable.UnknownException;
import org.omg.CORBA_2_3.portable.InputStream;
import org.omg.CORBA_2_3.portable.ObjectImpl;
import org.omg.CORBA_2_3.portable.OutputStream;

// Referenced classes of package de.tutorials.rmioveriiop.impl:
//            TimeServiceImpl

public class _TimeServiceImpl_Tie extends ObjectImpl
    implements Tie
{

    public _TimeServiceImpl_Tie()
    {
        target = null;
    }

    public String[] _ids()
    {
        return _type_ids;
    }

    public org.omg.CORBA.portable.OutputStream _invoke(String s, org.omg.CORBA.portable.InputStream inputstream, ResponseHandler responsehandler)
        throws SystemException
    {
        try
        {
            InputStream inputstream1 = (InputStream)inputstream;
            if(s.equals("_get_time"))
            {
                java.util.Date date = target.getTime();
                OutputStream outputstream = (OutputStream)responsehandler.createReply();
                outputstream.write_value(date, java.util.Date.class);
                return outputstream;
            } else
            {
                throw new BAD_OPERATION();
            }
        }
        catch(SystemException systemexception)
        {
            throw systemexception;
        }
        catch(Throwable throwable)
        {
            throw new UnknownException(throwable);
        }
    }

    public void deactivate()
    {
        _orb().disconnect(this);
        _set_delegate(null);
        target = null;
    }

    public Remote getTarget()
    {
        return target;
    }

    public ORB orb()
    {
        return _orb();
    }

    public void orb(ORB orb1)
    {
        orb1.connect(this);
    }

    public void setTarget(Remote remote)
    {
        target = (TimeServiceImpl)remote;
    }

    public org.omg.CORBA.Object thisObject()
    {
        return this;
    }

    private TimeServiceImpl target;
    private static final String _type_ids[] = {
        "RMI:de.tutorials.rmioveriiop.ITimeService:0000000000000000"
    };

}
```

So die Basis wär dann nun soweit. Nun starten wir den orbd (den findet man im %JAVA_HOME%/bin/orbd.exe). Dieser Server startet eine Corba Registry auf dem Port 900.

Nun müssen wir nur noch den Server und danach den Client mit den VM Optionen:

```
-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory -Djava.naming.provider.url=iiop://localhost:900
```
Server:

```
start java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory -Djava.naming.provider.url=iiop://localhost:900 de.tutorials.rmioveriiop.server.TimeServer
```
Client:

```
start java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory -Djava.naming.provider.url=iiop://localhost:900 de.tutorials.rmioveriiop.client.TimeServiceClient
```
starten und schon sollte das ganze funktionieren.

Gruß Tom


----------

