Contact us | Links

Accessing a .NET MarshalByRefObject with RMI/IIOP

In this tutorial a RMI/IIOP client calls a method on a .NET MarshalByRefObject: an adder. This .NET adder provides a method to add two double summands.

This tutorial consists of the following three steps:

  1. Implementing the Server
  2. Implementing the client
  3. Running the Demo

Implementing the .NET Server

In this section the .NET Remoting adder server is implemented. The following source files are created:

  • NAdder.cs: contains the adder implementation
  • NAdderServer.cs: contains code for publishing the adder object

The AdderImpl class implements the adder functionality:

    using System;
    using System.Runtime.Remoting;
    using Ch.Elca.Iiop.Idl;

    namespace Tutorial.GettingStarted {

        public class AdderImpl : MarshalByRefObject {
            public override object InitializeLifetimeService() {
                return null;
            public double add(double arg1, double arg2) {
                return arg1 + arg2;



Every .NET remoting object implementation has to extend MarshalByRefObject or a subclass of it. Therefore AdderImpl inherits from MarshalbyRefObject.
The AdderImpl class implements the adder functionality in the add method.
For controlling the lifetime of published objects the InitalizeLifetimeService method is overriden. The implementation in AdderImpl keeps a published object alive "forever".

Remark: It is also possible to separate the interface and the implementation of the adder.
A demo for this alternative is shown in upcoming tutorials.

The NAdderServer class creates an adder and publishes it with .NET Remoting.

    using System;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using Ch.Elca.Iiop;

    namespace Tutorial.GettingStarted {

        public class NAdderServer {

            public static void Main(string[] args) {
                // register the channel
                int port = 8087;
                IiopChannel chan = new IiopChannel(port);

                // publish the adder
                AdderImpl adder = new AdderImpl();
                string objectURI = "adder";
                RemotingServices.Marshal(adder, objectURI);
                Console.WriteLine("server running");



In a first step the IiopChannel must be registered with .NET remoting to enable access to .NET Remoting objects using the IIOP.NET channel. Afterwards an instance of AdderImpl is created and published. The IiopChannel includes a CORBA naming service, which encapsulates the .NET remoting nameing service. Therefore registering the adder object with a separate CORBA name service is not needed.

The files can be found here:


The two files are compiled in the following way:

  • create a directory bin inside the source directory
  • copy the IIOPChannel.dll into the bin directory
  • run the following command in the source directory:
    csc /t:exe /out:bin\AdderServer.exe /r:bin\IIOPChannel.dll *.cs

Implementing the RMI/IIOP Client

Creating IDL for CLS types

Before creating the java client, the CLS types must be mapped to IDL. This is done by the CLS to IDL generator (accoring to the CLS -> IDL mapping specification).
The following interface represents the CLS type AdderImpl in OMG ILD:

    module Tutorial {
        module GettingStarted {

            interface AdderImpl {

                double add(in double arg1, in double arg2) raises


Launch the following command in the directory, containing the .NET AdderServer binary, to generate the idl in the destination directory JAVA_SOURCES_DIRECTORY:
CLSIDLGenerator.exe -o JAVA_SOURCES_DIRECTORY Tutorial.GettingStarted.AdderImpl AdderServer.exe

Mapping IDL to Java

In the next step the IDL is mapped to java using the idlj tool. The predefined CORBA types are provided by the JDK ORB in the files orb.idl and ir.idl. Copy these two files into your java source directory JAVA_SOURCES_DIRECTORY. Use the following commands to create the needed java classes for the idl:

  • idlj Tutorial\GettingStarted\AdderImpl.idl
  • idlj Predef.idl

Client code

Now we are ready to implement the client. The following listing shows the implementation:

    import javax.naming.NamingException;
    import javax.naming.InitialContext;
    import javax.naming.Context;
    import javax.rmi.PortableRemoteObject;
    import Tutorial.GettingStarted.AdderImpl;

    public class AddClient {

        public static void main(String[] args) {

            try {
                BufferedReader reader = new BufferedReader(
                                            new InputStreamReader(;
                System.out.println("input the two summands");
                System.out.println("summand 1: ");
                double sum1 = Double.parseDouble(reader.readLine());
                System.out.println("summand 2: ");
                double sum2 = Double.parseDouble(reader.readLine());

                System.out.println("get inital naming context");
                Context ic = new InitialContext();
                System.out.println("ic received, retrieve add");
                Object objRef = ic.lookup("adder");
                AdderImpl adder = (AdderImpl) PortableRemoteObject.narrow(objRef,
                System.out.println("call add method");
                double result = adder.add(sum1, sum2);
                System.out.println("result: " + result);
            } catch (Exception e) {
                System.out.println("exception encountered: " + e);


The client first obtains a reference to the CORBA name service. Afterwards it looks up the adder at the name service. Finally the client uses the adder to add sum1 and sum2.

The file can be downloaded from here.


The client is compiled with the following commands:

  • javac -classpath .
  • javac -classpath . Tutorial\GettingStarted\*.java

Running the Demo

The server must be started first. This is done by running AdderServer.exe.

The client is afterwards started with the follwoing command line:

    java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
         -cp .

Remark: A CORBA naming service is automatically available at the same port the channel is listening on. The RMI/IIOP client contacts this namingservice to obtain object references from.

About this project

This project is maintained by Elca Informatique SA and was developed in collaboration with the Programming Languages and Runtime Systems Research Group of the ETH-Zurich as part of Dominic Ullmann's diploma thesis.

IIOP.NET Use Cases

Read the IIOP.NET success stories.


© 2003-2004 ELCA All Rights Reserved