loading gif

CORBA with Java

Author: Gokan EKINCI
First publication date: 2015-01-12
Updated: 2016-01-23
License: CC BY-NC-SA

Summary:
Before beginning this tutorial…
Introduction
Definitions
Further informations
What is the IDL ?
IDL/Java types
Modules
Interfaces, method prototypes, constants, and inheritance
Structures
Value types
Alias and arrays
Enumerations
Exceptions
Asynchronous operations
Practical Work Chapter 1: Generating IDL files
Practical Work Chapter 2: UML diagram
Practical Work Chapter 3: POA model (server-side only)
Practical Work Chapter 4: Server-side implementation
Practical Work Chapter 5: Client-side implementation
Practical Work Chapter 6: Bonus
Recurring errors
Conclusion: For or against CORBA?



Before beginning this tutorial…

Before beginning this tutorial:



Introduction

According to Wikipedia : The Common Object Request Broker Architecture (CORBA) is a standard defined by the Object Management Group (OMG) designed to facilitate the communication of systems that are deployed on diverse platforms. CORBA enables collaboration between systems on different operating systems, programming languages, and computing hardware. CORBA has many of the same design goals as object-oriented programming: encapsulation and reuse. CORBA uses an object-oriented model although the systems that use CORBA do not have to be object-oriented. CORBA is an example of the distributed object paradigm.

In order to establish a connection between a client and a CORBA server, the client and the server must have 1 ORB : a client-server application has 2 ORBs at least.

According to Wikipedia: In distributed computing, an object request broker (ORB) is a middleware which allows program calls to be made from one computer to another via a computer network, providing location transparency through remote procedure calls. ORBs promote interoperability of distributed object systems, enabling such systems to be built by piecing together objects from different vendors, while different parts communicate with each other via the ORB.

Let's analyze the following scheme:

Corba scheme

Steps:

  1. CORBA client invokes a remote method.
  2. CORBA client's Stub marshalize remote method invocation into CORBA request.
  3. CORBA request is send through the network from client's ORB.
  4. CORBA request is received by server's ORB.
  5. CORBA server's Skeleton unmarshalize CORBA request.
  6. CORBA server executes the service which is bound to the invoked method.
  7. CORBA server's Skeleton marshalize the CORBA response.
  8. CORBA response is send through the network from server's ORB.
  9. CORBA response is received by client's ORB.
  10. CORBA client's Stub unmarshalize CORBA response.

The thing we can notice about this scheme is that it looks more or less to the HTTP protocol (with a browser which represent the HTTP client and a web server)... so if we do an analogy between HTTP and CORBA, a HTTP client knows the server by its URL but how the CORBA client does know the CORBA server in this case? The answer is the "IOR" (see its definition on the next part)... to shorten it the IOR is an object which contains several informations which allows to identify a "servant" (the remote method). How to obtain this IOR? There's two standard ways:

  1. The CORBA server stores the IOR inside a file and the CORBA client find a way to retrieve this file for reading its content. It's possible to generate a proxy object from this IOR with an operation called "narrowing".
  2. The CORBA server has a service name "NameService", it's a program which runs as deamon on the server, it's more known as "orbd" or "tnameserv". Using the servers's host & port, and the name given to the service, the CORBA client can retrieve the IOR and generate a proxy object.

In our case we are going to use the second solution because it's cleaner.



Definitions

Oracle glossary for CORBA (detailed version here):



Further information

There are several implementation for CORBA, those implementations are interoperable:

You have to know what are the differences between:



What is the IDL?

The IDL (Interface Definition Language) is a language whose syntax is similar to C++, the principle of an IDL file is the same as XSD file (XML Schema Definition) or WSDL: to generate code (Java, C++, Python etc).

The IDL file is a contract between the CORBA server and the CORBA clients: they must use the same IDL contract in order to generate their code.

The IDL is an independant from implementation language used by client-side or server-side. We can have a C++ client and a Java server for example.

Some limitations:

IDL example:

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {
    interface CalculationService {
      long factorial(in long num);
    };
  };
};
package fr.ekinci;

public interface CalculationServiceOperations {
  int factorial(int num);
}
package fr.ekinci;

public interface CalculationService
  extends CalculationServiceOperations,
  org.omg.CORBA.Object,
  org.omg.CORBA.portable.IDLEntity
{ }



IDL/Java types

Types :

IDL Java (`in` mod) Java (`out` or `inout` mod)
void (return type) void void
boolean boolean org.omg.CORBA.BooleanHolder
char char org.omg.CORBA.CharHolder
wchar char org.omg.CORBA.CharHolder
octet byte org.omg.CORBA.ByteHolder
short short org.omg.CORBA.ShortHolder
unsigned short short org.omg.CORBA.ShortHolder
long int org.omg.CORBA.IntHolder
unsigned long int org.omg.CORBA.IntHolder
long long long org.omg.CORBA.LongHolder
unsigned long long long org.omg.CORBA.LongHolder
float float org.omg.CORBA.FloatHolder
double double org.omg.CORBA.DoubleHolder
long double Incompatible with Java Incompatible with Java
string java.lang.String org.omg.CORBA.StringHolder
wstring java.lang.String org.omg.CORBA.StringHolder
Object (different from java.lang.Object ! Used to handle IOR). org.omg.CORBA.Object org.omg.CORBA.ObjectHolder

Example of IDL method prototype:

void meth1();
long meth2(in long param1);
string meth3(in long param1, out octet param2, inout string param3);

in, out and inout keywords are mandatory for method parameters:



Modules

The equivalent of Java package in CORBA is module:

IDL Extract of code Java generated from IDL
module fr {
    module ekinci {
        // define interface
    };
};
package fr.ekinci;

// Java interface which implements `IDLEntity`

What you have to know :



Interfaces, method prototypes, constants, and inheritance

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {

    interface Parent{

      // Method prototypes
      void meth1();
      long meth2(in long param1);
      string meth3(
        in long param1, 
        out octet param2,
        inout string param3
      );

      // Constants 
      const long MAX = 10000;
      const float FACTOR = (10.0 - 6.5) * 3.91;  
    };

    // Inheritance
    interface Child : Parent{};

  };
};
package fr.ekinci;

public interface ParentOperations 
{
  void meth1 ();
  int meth2 (int param1);
  String meth3 (
    int param1,
    org.omg.CORBA.ByteHolder param2, 
    org.omg.CORBA.StringHolder param3
  );
}
package fr.ekinci;

public interface Parent 
    extends ParentOperations, 
    org.omg.CORBA.Object,
    org.omg.CORBA.portable.IDLEntity 
{  
  public static final int MAX = (int)(10000);
  public static final float FACTOR = 
   (float)((double)((double)(10.0 - 6.5) * 3.91));
}
public interface ChildOperations  
    extends fr.ekinci.ParentOperations
{  }
package fr.ekinci;

public interface Child
    extends ChildOperations,
    fr.ekinci.Parent,
    org.omg.CORBA.portable.IDLEntity
{  }

What you need to know:

The following command line idlj.exe -fall myfile.idl will generate 12 files:

Note : The ChildOperations interface inherits fromParentOperations, those interfaces contain method prototype in Java.



Structures

Structures et valuetypes allow to perform complex types.

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {
    struct Classe {
      short a;
      long b;
      double c;
      string d;
    };
  };
};
package fr.ekinci;

public final class Classe 
    implements org.omg.CORBA.portable.IDLEntity {
  public short a = (short)0;
  public int b = (int)0;
  public double c = (double)0;
  public String d = null;

  public Classe (){ } // ctor

  public Classe (short _a, int _b, double _c, String _d) {
    a = _a;
    b = _b;
    c = _c;
    d = _d;
  } // ctor

} // class Classe

What you need to know:



Value types

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {
    valuetype ParentValue {
      public long a;
      string getToto(in long param1);
    };

    valuetype ChildValue : ParentValue {
      private double b;
    };
  };
};
package fr.ekinci;

public abstract class ParentValue 
implements org.omg.CORBA.portable.StreamableValue {
  public int a = (int)0;

  public abstract String getToto (int param1);

  // See generated Java file for the rest
}
package fr.ekinci;

public abstract class ChildValue 
extends fr.ekinci.ParentValue {
    protected double b = (double)0;

    // See generated Java file for the rest
}

What you need to know:

The following command line idlj.exe -fall myfile.idl will generate 8 files:



Alias and arrays

Creating an array type attribute inside IDL struct:

IDL Extract of code Java generated from IDL
long tab[10];
public int tab[] = null;

/!\ : The size 10 is managed by xxxHelper class.

To create an array attribute without a predefined size in the IDL struct you have to use the sequence keyword:

IDL Extract of code Java generated from IDL
sequence<long> integerList;
public int integerList[] = null;

To use an array or sequence as a paramater type in a method prototype you have to use an alias with the typedef keyword:

IDL Extract of code Java generated from IDL
typedef long TabInt[10][10];
TabInt method(in TabInt param);
int[][] method(int[][] param);
typedef sequence<long> TabInt;
TabInt method(in TabInt param);
int[] method(int[] param);
typedef sequence<long> TabInt;
TabInt method(inout TabInt param);
int[] method(fr.ekinci.TabIntHolder param);

/!\ Warning: It's possible to use the typedef keyword inside or outside the interface which contains the method prototype with the array or sequence type parameter, however this instruction must be declared before to use the alias.



Enumerations

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {
    enum Toto {
      UN, DEUX, TROIS
    };
  };
};
package fr.ekinci;

public class Toto implements org.omg.CORBA.portable.IDLEntity
{
  private int __value;
  private static int __size = 3;
  private static fr.ekinci.Toto[] __array = 
    new fr.ekinci.Toto [__size];

  public static final int _UN = 0;
  public static final fr.ekinci.Toto UN = 
    new fr.ekinci.Toto(_UN);
  public static final int _DEUX = 1;
  public static final fr.ekinci.Toto DEUX = 
    new fr.ekinci.Toto(_DEUX);
  public static final int _TROIS = 2;
  public static final fr.ekinci.Toto TROIS = 
    new fr.ekinci.Toto(_TROIS);

  public int value ()
  {
    return __value;
  }

  public static fr.ekinci.Toto from_int (int value)
  {
    if (value >= 0 && value < __size)
      return __array[value];
    else
      throw new org.omg.CORBA.BAD_PARAM ();
  }

  protected Toto (int value)
  {
    __value = value;
    __array[__value] = this;
  }
} // class Toto

The following command line idlj.exe -fall myfile.idl will generate 3 files:



Exceptions

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {

    // Creation of the exception
    exception TransactionException{};


    // raises IDL = throws Java
    interface DistantTransaction {
      void prepare() 
        raises (TransactionException);

      void commit() 
        raises(TransactionException);

      void rollback() 
        raises(TransactionException);
    };

  };
};
package fr.ekinci;

public interface DistantTransaction 
    extends DistantTransactionOperations,
    org.omg.CORBA.Object,
    org.omg.CORBA.portable.IDLEntity 
{  } // interface DistantTransaction
package fr.ekinci;

public final class TransactionException 
    extends org.omg.CORBA.UserException {

  public TransactionException () {
    super(TransactionExceptionHelper.id());
  } // ctor

  public TransactionException (String $reason) {
    super(TransactionExceptionHelper.id() + "  " + $reason);
  } // ctor

} // class TransactionException

What you need to know:

The following command line idlj -fall myfile.idl will generate 9 files:



Asynchronous operations

CORBA methods are executed synchronously (like RMI methods in Java), it means that if the server takes two seconds to execute a method, the client has to wait those two seconds + the network exchange time between the client and the server. However there is a oneway keyword to make an asynchronous method: the client does not wait until the server has finished executing the oneway method and passes directly to the following instruction.

To implement an asynchronous method you have to respect some constraints:

Example:

module fr {
  module ekinci {
    interface Asynchronous {

      oneway void farewell();

    };
  };
};

List of files generated after executing the following command line idlj -fall myfile.idl: _AsynchronousStub.java, Asynchronous.java, AsynchronousHelper.java, AsynchronousHolder.java, AsynchronousOperations.java, AsynchronousPOA.java

/!\ Warning: If you're familiar with multi threaded environments and have knowledge of concurrency issues, you know that asynchronous methods should be handled with caution.



Practical Work Chapter 1: Generating IDL files

For generating Java classes from IDL files, we are going to use the "idlj" program in the JDK, this program has the ".exe" extension under Windows. You should find this program in the JDK directory "jdkxxx/bin/".

We are goind to use the following command line: idlj -fall <Insert your IDL file name> example: idlj -fall calcul.idl
With the -fall parameter, we are going to generate several Java files for the client-side and server-side.
The number of generated files depends on the elements used in the idl file. For example, for each enumeration (enum) added in the idl file idlj will generate 3 additional Java files.

Otherwise :

Create an IDL file with the following content:

IDL Extract of code Java generated from IDL
module fr {
  module ekinci {
    interface CalculationService {
      long factorial(in long num); 
    }; 
  };
};
package fr.ekinci;

public interface CalculationService
    extends CalculationServiceOperations, 
    org.omg.CORBA.Object, 
    org.omg.CORBA.portable.IDLEntity 
{  } // interface CalculationService

6 files will be generated if we execute the following command line idlj -fall calcul.idl:

File Description
CalculationServicePOA.java This file contains an abstract class which represent the skeleton of the server
_CalculationServiceStub.java This file contans a class which represent the stub of the client
CalculationService.java This file contains our Java interface `CalculationService`. `CalculationService` interface inherits from `CalculationServiceOperations`, `org.omg.CORBA.Object` and `org.omg.CORBA.portable.IDLEntity`
CalculationServiceHelper.java This file contains an abstract class for narrowing and handling `org.omg.CORBA.Any` type
CalculationServiceHolder.java This file contains a final class for handling `out` and `inout` mod parameters
CalculationServiceOperations.java This interface contains method prototypes of `CalculationService`, for our case it only contains `factorial()` method



Practical Work Chapter 2: UML diagram

The following UML diagram gives a better preview on the hierarchy of generated classes :
UML CORBA

What you need to know :



Practical Work Chapter 3: POA model (server-side only)

There are two ways to implement the POA model for the server-side:

The difference between those 2 models?
If we choose the Inheritance Model, the implementation class must inherit from CalculationServicePOA class, whereas if we choose the Tie Delegation Model, the implementation class must implement the CalculationServiceOperations interface. As there is no multiple inheritance in Java, the Tie Delegation Model is useful for liberating a slot and implementation class may inherit from another class, however there this model has also a drawback: an additional method is called each time you call a remote method.

Sun/Oracle's quote (source) :

You might want to use the Tie model instead of the typical Inheritance model if your implementation must inherit from some other implementation. Java allows any number of interface inheritance, but there is only one slot for class inheritance. If you use the inheritance model, that slot is used up. By using the Tie Model, that slot is freed up for your own use. The drawback is that it introduces a level of indirection: one extra method call occurs when invoking a method.

/!\ : Multiple inheritance has never been an inevitable solution, it is entirely possible to use a behaviour pattern with composition.

The difference between these two POA models at the server implementation is relatively low, there's only two line to change:

The Inheritance Model The Tie Delegation Model
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(calculImpl);

CalculationService href = CalculationServiceHelper.narrow(ref);
CalculationServicePOATie tie = new CalculationServicePOATie(calculImpl, rootpoa);

CalculationService href = tie._this(orb);

I will use the Inheritance Model in the next chapter.

Implicit activation of the servant:

Useful classes for :

client-side (-fclient option) server-side (-fserver option)
CalculationService, CalculationServiceOperations, CalculationServiceHelper, CalculationServiceHolder, _CalculationServiceStub CalculationService, CalculationServiceOperations, CalculationServicePOA

/!\ Warning : If we use the Inheritance Model the server implementation requires CalculationServiceHelper class, if we use the Tie Delegation Model the server implementation requires CalculationServiceHelper and CalculationServicePOATie classes, but the idlj -fserver calcul.idl command line does not generate CalculationServiceHelper or CalculationServicePOATie classes, if you choose:

/!\ : There's another model called BOA, which is an ancestor of the POA model for implemeting server-side code, although deprecated, a tutorial called "ImplBase" about this model is still available for those using Java 1.3 (link).



Practical Work Chapter 4: Server-side implementation

I. Take the IDL shown in first chapter of this PW:

module fr {
  module ekinci {
    interface CalculationService {
      long factorial(in long n);
    };
  };
};


II. Generate the required files with idlj

To use the Inheritance Model, execute the following command line idlj -fall calcul.idl.
To use the Tie Delegation Model, execute the following command line idlj -fall calcul.idl, then the following command line idlj -fallTIE calcul.idl.

The reason why you have to execute 2 command lines for the Tie Delegation Model (source):

Because it is not possible to generate ties and skeletons at the same time, they must be generated separately.

/!\ : If you don't want to use the Tie Delegation Model, the second command line is obviously not necessary.


III. Create the implementation class CalculationServiceImpl.java

The xxxPOA.java file (or xxxPOATie.java for a Tie implementation) represents the server's skeleton.

Now we are going to create the implementation class CalculationServiceImpl which inherits from CalculationServicePOA and implements all the methods defined in the CalculationServiceOperations interface:

import fr.ekinci.CalculationServicePOA;

public class CalculationServiceImpl extends CalculationServicePOA {

  @Override
  public int factorial(int n){
    if (n < 2) {
      return 1;
    }

    int c = n;
    while(c != 1){
      n *= --c;
    }

    return n; 
  }
}

/!\ Warning : You can notice that the factorial implementation don't handle the case where n is less than zero and return 1.


IV. Create a MainServer class for server initialization

import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.CosNaming.*;
import fr.ekinci.*;


/**
 * Class for launching the server program
 * @author Gokan EKINCI
 */
public class MainServer {
    public static void main(String args[]){
        try {
            // ORB initialization
            ORB orb = ORB.init(args, null);

            // Get the RootPOA and activate the POAManager
            POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
            rootpoa.the_POAManager().activate();

            // Create a servant (instance of the implementation class) and bind it to the ORB
            CalculationServiceImpl calculImpl = new CalculationServiceImpl();


            /* *** BEGIN INHERITANCE MODEL (you can see previous chapters for using the Tie Delegation Model) *** */

            // Get servant's reference
            org.omg.CORBA.Object servantRef = rootpoa.servant_to_reference(calculImpl);

            CalculationService service = CalculationServiceHelper.narrow(servantRef);

            /* *** END INHERITANCE MODEL *** */

            // Get naming service's reference
            org.omg.CORBA.Object nsRef = orb.resolve_initial_references("NameService");
            NamingContextExt nce = NamingContextExtHelper.narrow(nsRef);

            // Create a name for the service and bind it
            String serviceName = "MathServices";
            NameComponent nc[] = nce.to_name(serviceName);
            nce.rebind(nc, service);

            // Start the service and wait for CORBA requests from clients
            System.out.println("Treating clients requests ...");
            orb.run(); // Waiting for new CORBA clients

        } catch (Exception e){
            System.err.println(e);
        }
    }
}



V. Start the server : Launch orbd (daemon process)

This program is in the same directory than idlj: "/jdkxxx/bin".

Command line for executing ordb :

OS Command line
Linux orbd -ORBInitialPort 1050 -ORBInitialHost localhost&
Windows start orbd -ORBInitialPort 1050 -ORBInitialHost localhost

What you need to know:

Windows preview:

Launch ORBD

A Windows warning message can be launched, authorize the access:

Windows pop-up

A new console is automatically launched:

ORBD is running

Remember: To quit ordb do Ctrl + C (if you quit the clients won't be able to access the service).



VI. Start the server program MainServer

Start the server program with the following command line if it's a runnable JAR:
start java -jar MainServer.jar -ORBInitialPort 1050 -ORBInitialHost localhost

If you launch the MainServer program from Eclipse, go to Run Configurations… > Arguments > Program Arguments and copy/past this: -ORBInitialPort 1050 -ORBInitialHost localhost.



Practical Work Chapter 5: Client-side implementation

Create a MainClient class for client initialization:

import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import fr.ekinci.*;


/**
 * Class for launching the client program
 * @author Gokan EKINCI
 */
public class MainClient {
    public static void main(String args[]){
        try {
            // ORB initialization
            ORB orb = ORB.init(args, null);

            // Get naming service's reference
            org.omg.CORBA.Object nsRef = orb.resolve_initial_references("NameService");
            NamingContextExt nce = NamingContextExtHelper.narrow(nsRef);

            // Generate a proxy object
            String serviceName = "MathServices";
            CalculationService service = CalculationServiceHelper.narrow(nce.resolve_str(serviceName));

            System.out.println("Server's response: " + service.factorial(5)); // 120
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Launch your client program from your IDE, OR compile your program with javac and launch the program with java, OR use the following command line if you have transformed your project to JAR file :
java -jar MainClient.jar -ORBInitialPort 1050 -ORBInitialHost localhost

Remember: You need to launch the server program (MainServer) before the client program (MainClient).



Practical Work Chapter 6: Bonus

In the previous chapters we saw how CORBA implementation code can be long to write... and that tedious process will still be repetitive. If the implementation code was not as difficult CORBA should not have lose its popularity, who knows?

In this part we are going to realize the same exercise but with only a few instructions.

Download the corba-wrapper project from this GitHub link. You can use a Git command or just copy/past CORBAServer and CORBAClient classes in your project.

UML diagram CORBA Sever

Create a server project and use the CORBAServer class:

import fr.ekinci.*;
import fr.ekinci.corbawrapper.CORBAServer;

public class MainServer {
    public static void main(String args[]) throws Exception {
        CORBAServer server = new CORBAServer("127.0.0.1", 1050); 

        // Add a service      
        server.addService("MathServices", new CalculationServiceImpl(), CalculationServiceHelper.class); 

        // Start the service
        server.run();                                                          
    }
}

/!\ : CalculationServiceImpl inherits from CalculationServicePOA (cf: use the Inheritance Model, NOT the Tie Delegation Model).

UML diagram CORBA Client

Create a client project and use the CORBAClient class:

import fr.ekinci.*;
import fr.ekinci.corbawrapper.CORBAClient;

public class MainClient {
    public static void main(String args[]) throws Exception {
        CORBAClient client = new CORBAClient("127.0.0.1", 1050);

        // Get the proxy object   
        CalculationService calcul = client.<CalculationService, CalculationServiceHelper>lookup("MathServices", CalculationServiceHelper.class);

        // Invoke remote methods
        System.out.println("Server's response: " + calcul.factorial(5)); // 120
    }
}

Launch orbd first, then the server project, then client project, the result will be the same as in the previous chapters. Simple to set up, isn't it?



Recurring errors

It's a safe bet that the CORBA client/server program will work without any problem under localhost, but it may not the case with two machines :

WARNING: "IOP00410201: (COMMFAILURE) Connection failure: socketType:
IIOP
CLEAR_TEXT; hostname: 127.0.0.1;

... simply go on the server machine et replace the localhost address by the real IP address in the /etc/hosts file, finally reboot your machine for the changes to take effect. Note that this problem is also faced by those who use RMI with Linux, the solution is the same.



Conclusion: For or against CORBA?

Let's list some advantages and disadvantages to use CORBA...

Advantages Disadvantages
CORBA use a binary based protocol (GIOP/IIOP), it's more efficient (lightweight and fast) than text based protocols (ex: web services, cf benchmark read §3.4). At the time of writing this tutorial, the last specification of CORBA is 3.3 (November 2012), but most of the latest implementations in computer languages are based on the standard 2.3.1 (October 1999). At the time CORBA was considered as a good alternative to Microsoft's DCOM, but since other technologies such as web services have supplanted CORBA.
Unlike RMI, CORBA has been designed to be a heterogeneous solution, you can have a Java server and a C++ client. Unlike web services which use HTTP adapted for WAN (Wide Area Network), CORBA can be blocked by firewalls because because the port number changes dynamically by the CORBA server. We limit the use of CORBA to LAN.
The first specification of CORBA dates from August 1991, it's a mature standard. OMG's will is to make CORBA heterogeneous, however the IDL file may contain some incompatibilities with implementation languages (Java, C++ etc). An IDL file which perfectly generates C++ code may have a problem for generating Java code (ex: impossible to transcribe the IDL's `long double` type to Java).
Writing a client/server implementation in CORBA is very long, very repetitive, very "old-school", but we have seen that a simple wrapper project like corba-wrapper can remove those difficulties.

Today there is another open source competitor to CORBA: gRPC. The latter is a protocol created by Google, interoperable, has an official implementation for many languages (C++, Java, Python, C# etc), binary protocol (HTTP/2)... but gRPC is not enough known yet.
Would you like to see a gRPC tutorial ? Feel free to tell me in the comments.