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
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();
}