Kothar Labs Contact Me

Brief introduction to PolyORB

Mon, 10 Nov 2008 / blog / ada / polyorb

I've been experimenting with PolyORB at work, and the documentation, while fine for configuring and compiling your application, is sorely lacking on any help with implementing your CORBA servants.

Here I'll attempt to provide some brief hints on how to do things that don't seem to be described in the documentation. The PolyORB mailing list is a good place to find more information.


Well Known Services

I wanted to be able to use a simple corbaloc with an object ID which doesn't change, along the lines of:

'corbaloc:iiop:[email protected]:2809/MyServant'

This doesn't seem to be possible as of yet, but this message suggests that the easiest thing to do is to use a “Well Known Service” instead.

You can initialise a new well-known service using the following code:

declare  
   Ref : CORBA.Object.Ref;  
   Obj : constant CORBA.Impl.Object_Ptr := new Service.Impl.Object;  

begin  
   PolyORB.CORBA_P.Server_Tools.Initiate_Well_Known_Service  
      (PortableServer.Servant (Obj), "MyServant", Ref);  
   -- Now do something with Ref;  
end;

Which will produce a corbaloc which looks like this:

'corbaloc:iiop:[email protected]:2809/MyServant/000000024fF0000000080000000'

It's not quite as concise, but it is always the same.

Binding Interfaces

Telling PolyORB which interfaces to bind to is still something of a mystery to me. If you don't specify a default address, the ORB will bind to every interface. The problem comes when the corbaloc now uses the 'default' address for your hostname (specified in the hosts file), which in my case is 127.0.1.1. This isn't much help when you want to connect to a remote computer.

To specify a default address manually, you need to create a polyorb.conf file. Mine looks like this:

###############################################################  
# IIOP Global Settings  

[iiop]  

# Preference level for IIOP  
polyorb.binding_data.iiop.preference=1  

# IIOP's default address  
polyorb.protocols.iiop.default_addr=192.168.1.20  

# IIOP's default port  
polyorb.protocols.iiop.default_port=2809  

# IIOP's alternate addresses  
polyorb.protocols.iiop.alternate_listen_addresses=127.0.0.1:2809  

# Default GIOP/IIOP Version  
polyorb.protocols.iiop.giop.default_version.major=1  
polyorb.protocols.iiop.giop.default_version.minor=2

This file needs to be in the current directory - not in the path, not with the executable, but in the current working directory.

I'm still working on a way to deal with dynamically assigned IP addresses. Ideally, the corbaloc would include the hostname rather than an IP address, giving us something like this:

'corbaloc:iiop:[email protected]:2809/MyServant/000000024fF0000000080000000'

but that has its own problems (the host name should be fully qualified if you expect it to be found on the internet for example).

I've no idea how to get the utilities to generate the correct references for me, so I'd have to manually edit them to use the host name. The Object_To_Corbaloc function simply returns the corbaloc for the “best profile” - whatever that is.

Looking at the implementation, this is based entirely on transport preference levels, so i can't see an easy way to prefer one address over another except manually specifying the default.

Another huge problem is that even though the ORB binds to all interfaces, any IORs it generates use the default IP address! So if I leave the default as 127.0.1.1, but connect to 192.168.1.20, any object references passed to the client from the server will use 127.0.0.1. Not very useful.

You can read more about the problem in this post on the mailing list.

Using Sequences

Sequences were a bit confusing to me at first, since I'm more familiar with the Java bindings which map everything to standard generic List objects. This is mostly just to provide an example of using them.

In PolyORB, each sequence is mapped to a new generic package which, for IDL-defined interfaces at least, contains 'Forward' objects. Each reference must be converted to its equivalent Forward before it can be inserted into the sequence. This is done using the 'Convert' package defined with each interface.

That's probably not very clear, but below is an example.

with jobs;  
with jobs.Helper;  
with jobs.Job.Helper;  
with jobs.Job.Impl;  
with PolyORB.Sequences.Unbounded;  

function newJob  
     (Self : not null access Object;  
      config : jobs.JobConfig)  
     return jobs.Job.Ref  
   is  
      Root_POA : PortableServer.POA.Local_Ref :=  PolyORB.CORBA_P.Server_Tools.Get_Root_POA;  

      Obj : constant jobs.Job.Impl.Object_Ptr := new jobs.Job.Impl.Object;  
      Ref : CORBA.Object.Ref;  

      Result : jobs.Job.Ref;  

      use jobs.Job.Convert_Forward;  
   begin  
      -- Register new servant with Root POA  
      Ref := PortableServer.POA.Servant_To_Reference  
        (Root_POA, PortableServer.Servant (Obj));  

      -- Downcast to Job reference  
      Result := jobs.Job.Helper.Unchecked_to_ref(ref);  

      -- Append to list of current jobs  
      Append(Self.Job_List, To_Forward(Result));  

      return Result;  
   end newJob;