c++corbaomniorbnameservice

CORBA omniORB unable to get remote object after resolving name context


I have an IDL as below

module IClientServer {

  interface IClient 
  {
    void serverResponse(in string name, in string data);

    void start();

    void stop();

    void shutdown();

  };

  interface IServer 
  {

     // Server calls back to client just once in a
     // recursive call before returning.
     // void one_time(in CallBack cb, in string mesg);
    void DataFromX(in string name,in string data,in long lbytes,in short usg);

    void Authenticate(in IClient client, in string dataToNegotiate);

     // Shuts down the server.
    void shutdown();

  };
};

for which I generated proxy & skeleton using idl2cpp utility (onmiORB) and linked generated files to server & client app as suggested in the document

Then I started name service (omniNames) and added registry key omniORB\InitRef as suggested in documentation for the server & client apps to connect without using commandline arguments

Below is the server code

int _tmain(int argc, _TCHAR* argv[])
{
    try 
    {
    int argc = 0;
        _BRDTRACE("Initializing....\n");
        CORBA::ORB_var orb = CORBA::ORB_init(argc, NULL);
//          cerr << "Initialized." << endl;

        CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
        _BRDTRACE("Resolved.\n");


        PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
        _BRDTRACE("Narrowed..\n");

            // Obtain a reference to the object, and register it in
            // the naming service.
        server_i* myserver = new server_i();
//          cerr << "Constructed." << endl;

        obj = myserver->_this();
        _BRDTRACE("obj retrieved.\n");

        CORBA::String_var x;
        x = orb->object_to_string(obj);
        _BRDTRACE("obj to string.\n");

        if( !bindObjectToName(orb, obj) )
        {
//            cerr << "Failed to bind obj to name." << endl;
          throw;
        }

        _BRDTRACE("binded\n");
        myserver->_remove_ref();
//          cerr << "removed ref." << endl;

        PortableServer::POAManager_var pman = poa->the_POAManager();
        pman->activate();
        _BRDTRACE("activated.\n");

//          cerr << "Executing..." << endl;
        orb->run();
        _BRDTRACE("Terminated.\n");

        myserver->shutdown();
//          cerr << "Shutdown." << endl;

    }
    catch(CORBA::SystemException&) 
    {
        _BRDTRACE("Caught CORBA::SystemException.\n");
    }
    catch(CORBA::Exception&) {
        _BRDTRACE("Caught CORBA::Exception.\n");
    }
    catch(omniORB::fatalException&) 
    {
        _BRDTRACE("Caught omniORB::fatalException:\n");
//          cerr << "  file: " << fe.file() << endl;
//          cerr << "  line: " << fe.line() << endl;
//          cerr << "  mesg: " << fe.errmsg() << endl;
    }
    catch(...) {
        _BRDTRACE("Caught unknown exception.\n");
    }

}

static CORBA::Boolean
bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
{
  CosNaming::NamingContext_var rootContext;

  try {
    // Obtain a reference to the root context of the Name service:
    CORBA::Object_var obj;
    obj = orb->resolve_initial_references("NameService");

    // Narrow the reference returned.
    rootContext = CosNaming::NamingContext::_narrow(obj);
    if( CORBA::is_nil(rootContext) ) {
      _BRDTRACE("Failed to narrow the root naming context.\n");
      return 0;
    }
  }
  catch(CORBA::ORB::InvalidName& ex) {
    // This should not happen!
    _BRDTRACE("Service required is invalid [does not exist].\n");
    return 0;
  }

  try {
    // Bind a context called "test" to the root context:

    CosNaming::Name contextName;
    contextName.length(1);
    contextName[0].id   = (const char*) "birdseye";       // string copied
    contextName[0].kind = (const char*) "collections_context"; // string copied
    // Note on kind: The kind field is used to indicate the type
    // of the object. This is to avoid conventions such as that used
    // by files (name.type -- e.g. test.ps = postscript etc.)

    //CosNaming::NamingContext_var testContext;
    try {
      // Bind the context to root.
      rootContext->bind(contextName, objref);
    }
    catch(CosNaming::NamingContext::AlreadyBound& ex) {
      // If the context already exists, this exception will be raised.
      // In this case, just resolve the name and assign testContext
      // to the object returned:
      CORBA::Object_var obj;
      obj = rootContext->resolve(contextName);
      CosNaming::NamingContext_var testContext = CosNaming::NamingContext::_narrow(obj);
      if( CORBA::is_nil(testContext) ) {
        _BRDTRACE("Failed to narrow naming context.\n");
        return 0;
      }
    }
  } catch(CORBA::COMM_FAILURE& ex) {
   _BRDTRACE("Caught system exception COMM_FAILURE -- unable to contact the naming service.\n");
    return 0;
  }
  catch(CORBA::SystemException&) {
    _BRDTRACE("Caught a CORBA::SystemException while using the naming service.\n");
    return 0;
  }

  return 1;
}

But the below code in the client side returns nil object after name context resolution. Not able to figure out the issue. Please help!

int _tmain(int argc, _TCHAR* argv[])
{
    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
    CORBA::Object_var objRef = orb->resolve_initial_references("NameService");
    CORBA::Object_var obj = getObjectReference(orb);
    IClientServer::IServer_var svr = IClientServer::IServer::_narrow(obj.in());
  if( CORBA::is_nil(svr) ) {    **//THIS IS WHERE THE ISSUE IS**
 //   _BRDTRACE("cb_client: The server reference is nil!\n");
    return 0;
  }
    return 0;
}

static CORBA::Object_ptr
getObjectReference(CORBA::ORB_ptr orb)
{
  CosNaming::NamingContext_var rootContext;

  try {
    // Obtain a reference to the root context of the Name service:
    CORBA::Object_var obj;
    obj = orb->resolve_initial_references("NameService");

    // Narrow the reference returned.
    rootContext = CosNaming::NamingContext::_narrow(obj);
    if( CORBA::is_nil(rootContext) ) {
//      cerr << "Failed to narrow the root naming context." << endl;
      return CORBA::Object::_nil();
    }
  }
  catch(CORBA::ORB::InvalidName& ) {
    // This should not happen!
    return CORBA::Object::_nil();
  }
  // Create a name object, containing the name test/context:
  CosNaming::Name name;
  name.length(1);

  name[0].id   = (const char*) "birdseye";       // string copied
  name[0].kind = (const char*) "collections_context"; // string copied
  // Note on kind: The kind field is used to indicate the type
  // of the object. This is to avoid conventions such as that used
  // by files (name.type -- e.g. test.ps = postscript etc.)


  try {
    // Resolve the name to an object reference.
    return rootContext->resolve(name);
  }
  catch(CosNaming::NamingContext::NotFound& nf) {
  }
  catch(CORBA::COMM_FAILURE& ) {
  }
  catch(CORBA::SystemException&) {
  }

  return CORBA::Object::_nil();
}

UPDATE-5PM: Infact the server side code also has same issue server->authenticate is never called due to nil reference.

Guess : Can there be an issue with proxy & stubs generated with idl2cpp tool?

UPDATE-7:30PM The ambiguity on stubs not ok is also gone, the issue still persists after regenerating the stubs & rebuilding both client & server apps again

UPDATE 3-31|11AM I am using omniORB 4.0.3 which is over 10 year old. This has worked great in earlier windows OS versions compiled with VC6, I doubt there is issue when recompiled on VS 2008. Just thinking of upgrade to ommiORB 4.2 released last year. Just clueless whatsoever...

UPDATE 3-31|5:30PM Currently building omniORB4.2.1 source code. While I do this I still want to know if there is any issue linking the .lib files that are generated in older systems. In this case the omniORB .lib files I am using in Windows 7 is built on Windows XP, would that be an issue? Even this post could not answer, I have a old .lib that compiled & linked well without any issues & even the runtime it did not crash as well

UPDATE 4-01|4:30PM Actually I noticed there is no server running, the server code I posted earlier is also client, I now updated real server code(the code which binds name to server obj). But the issue remains same even after this correction


Solution

  • Finally I fixed the issue. There are 2 issues with the code issue 1 I already updated in question (missing server code) issue 2 is with name context binding..

    below is modified version of bindObjectToName in server

    static CORBA::Boolean
    bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
    {
      CosNaming::NamingContext_var rootContext;
    
      try {
        // Obtain a reference to the root context of the Name service:
        CORBA::Object_var obj;
        obj = orb->resolve_initial_references("NameService");
    
        // Narrow the reference returned.
        rootContext = CosNaming::NamingContext::_narrow(obj);
        if( CORBA::is_nil(rootContext) ) {
    //      cerr << "Failed to narrow the root naming context." << endl;
          return 0;
        }
      }
      catch(CORBA::ORB::InvalidName& ex) {
        // This should not happen!
      //  cerr << "Service required is invalid [does not exist]." << endl;
        return 0;
      }
    
      try {
        // Bind a context called "test" to the root context:
    
        CosNaming::Name contextName;
        contextName.length(1);
        contextName[0].id   = (const char*) "birdsEYE";       // string copied
        contextName[0].kind = (const char*) "DataCollectionS"; // string copied
        // Note on kind: The kind field is used to indicate the type
        // of the object. This is to avoid conventions such as that used
        // by files (name.type -- e.g. test.ps = postscript etc.)
    
        CosNaming::NamingContext_var testContext;
        try {
          // Bind the context to root.
          testContext = rootContext->bind_new_context(contextName);
        }
        catch(CosNaming::NamingContext::AlreadyBound& ex) {
          // If the context already exists, this exception will be raised.
          // In this case, just resolve the name and assign testContext
          // to the object returned:
          CORBA::Object_var obj;
          obj = rootContext->resolve(contextName);
          testContext = CosNaming::NamingContext::_narrow(obj);
          if( CORBA::is_nil(testContext) ) {
        //    cerr << "Failed to narrow naming context." << endl;
            return 0;
          }
        }
    
        // Bind sender :
        CosNaming::Name objectName;
        objectName.length(1);
        objectName[0].id   = (const char*) "clienT";   // string copied
        objectName[0].kind = (const char*) "sendeR"; // string copied
    
        try {
          testContext->bind(objectName, objref);
        }
        catch(CosNaming::NamingContext::AlreadyBound& ex) {
          testContext->rebind(objectName, objref);
        }
        // Note: Using rebind() will overwrite any Object previously bound
        //       to /test/Echo with obj.
        //       Alternatively, bind() can be used, which will raise a
        //       CosNaming::NamingContext::AlreadyBound exception if the name
        //       supplied is already bound to an object.
    
        // Bind receiver :
        CosNaming::Name objectName2;
        objectName2.length(1);
        objectName2[0].id   = (const char*) "clienT";   // string copied
        objectName2[0].kind = (const char*) "receiveR"; // string copied
    
        try {
          testContext->bind(objectName2, objref);
        }
        catch(CosNaming::NamingContext::AlreadyBound& ex) {
          testContext->rebind(objectName2, objref);
        }
    
    
        // Amendment: When using OrbixNames, it is necessary to first try bind
        // and then rebind, as rebind on it's own will throw a NotFoundexception if
        // the Name has not already been bound. [This is incorrect behaviour -
        // it should just bind].
    
      }
      catch(CORBA::COMM_FAILURE& ex) {
        //cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
        //     << "naming service." << endl;
        return 0;
      }
      catch(CORBA::SystemException&) {
        //cerr << "Caught a CORBA::SystemException while using the naming service."
        // << endl;
        return 0;
      }
    
      return 1;
    }
    

    And below the modified getObjectReference in client code static CORBA::Object_ptr

    getObjectReference(CORBA::ORB_ptr orb)
    {
      CosNaming::NamingContext_var rootContext;
    
      try {
        // Obtain a reference to the root context of the Name service:
        CORBA::Object_var obj;
        obj = orb->resolve_initial_references("NameService");
    
        // Narrow the reference returned.
        rootContext = CosNaming::NamingContext::_narrow(obj);
        if( CORBA::is_nil(rootContext) ) {
    //      cerr << "Failed to narrow the root naming context." << endl;
          return CORBA::Object::_nil();
        }
      }
      catch(CORBA::ORB::InvalidName& ex) {
        // This should not happen!
      //  cerr << "Service required is invalid [does not exist]." << endl;
        _BRDTRACE("getObjRef: service required is invalid.\n");
        exit(0);
        return CORBA::Object::_nil();
      }
    
    
      // Create a name object, containing the name test/context:
      CosNaming::Name name;
      name.length(2);
    
      name[0].id   = (const char*) "birdsEYE";       // string copied
      name[0].kind = (const char*) "DataCollectionS"; // string copied
      name[1].id   = (const char*) "clienT";
      name[1].kind = (const char*) "sendeR";
      // Note on kind: The kind field is used to indicate the type
      // of the object. This is to avoid conventions such as that used
      // by files (name.type -- e.g. test.ps = postscript etc.)
    
    
      try {
        // Resolve the name to an object reference.
        return rootContext->resolve(name);
      }
      catch(CosNaming::NamingContext::NotFound& ex) {
        // This exception is thrown if any of the components of the
        // path [contexts or the object] aren't found:
        //cerr << "Context not found." << endl;
        _BRDTRACE("getObjRef: context not found.\n");
        exit(0);
      }
      catch(CORBA::COMM_FAILURE& ex) {
        //cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
         //    << "naming service." << endl;
        _BRDTRACE("getObjRef: caught system exception COMM_FAILURE.\n");
        exit(0);
      }
      catch(CORBA::SystemException&) {
        //cerr << "Caught a CORBA::SystemException while using the naming service."
         //<< endl;
        _BRDTRACE("getObjRef: caught system exception while using the name service.\n");
        exit(0);
      }
    
      return CORBA::Object::_nil();
    }