Search code examples
javacorbaidl

Can I use an interface defined in IDL as a return type of a method of another IDL interface?


Let's say I create following IDL file:

module ProviderTest {
    interface Multiplier {
        long twice(in long number);
    };

    interface MultiplierProvider {
        Multiplier get();
    };
};

To be able later perform a call like that on the client side (in Java):

MultiplierProvider provider = /* obtain a stub form ORB */
Multiplier multiplier = provider.get();
int four = multiplier.twice(2);

Java IDL compiler generates code for that IDL without complains, but I'm having trouble writing an implementation for MultiplierProvider servant. It's get() method has a return type of Multiplier, which is a generated interface. In order to implement MultiplierProvider, I extend MultiplierProviderPOA, but I don't have a suitable implementation class for Multiplier so I cannot implement the get() method.

Normally (if Multiplier wasn't referenced from the MupltiplierProvider), on the server side I would extend MultiplierPOA (generated class) and then publish it via the Naming Service. The thing is MultiplierPOA does not implement the Multiplier interface, so it's instances cannot be returned from MultiplierProvider.get().

Am I missing some fundamental principle here, that you cannot do things like that with CORBA IDL (or maybe that Java's IDL support cannot handle such case)? If interfaces like that are possible to implement - how does the implementation work?


Solution

  • Recently I've found a solution that works for me. So, in order to get a reference of type Multiplier, that can be returned from the MultiplierPorider.get() method, one can create an instance of the class derived from MultiplierPOA, then register it with the ORB and at the same time get a stub from the ORB, which then can be returned from the get() method. Here's the code:

    MultiplierImpl servant = new MultiplierImpl();
    POA rootPOA = /* obtain a reference to the Root Object Adapter from the ORB */
    /* get a reference of type Multiplier: 
       register the servant with POA and get a stub for it */
    Multiplier multiplier = MultiplierHelper.narrow(rootPOA.servant_to_reference(servant));
    /* construct the MultiplierProvider servant passing the stub to it */
    MultiplierProviderImpl provider = new MultiplierProviderImpl(multiplier);
    /* then register provider in Naming Context, so it can be obtained by the client using the name */
    

    I've also checked, that after the servant is registered in that way, one can use following code to obtain the reference to the stub (thanks to this answer):

    /* method _this() is defined in MultiplierPOA */
    Multiplier stub = servant._this();
    

    Although the implementation seems trivial, just to be clear, the MultiplierProviderImpl class could look like that:

    public class MultiplierProviderImpl extends MultiplierProviderPOA {
    
        private final Multiplier multiplier;
    
        public MultiplierProviderImpl(Multiplier multiplier) {
            this.multiplier = multiplier;
        }
    
        @Override
        public Multiplier getMultiplier() {
            return multiplier;
        }
    }
    

    , and the MultiplierImpl could look like that:

    public class MultiplierImpl extends MultiplierPOA {
    
        @Override
        public void twice(int number) {
            return number * 2;
        }
    }