[omniORB] omniORBpy newbie questions

Duncan Grisby dgrisby@uk.research.att.com
Thu, 10 Feb 2000 17:35:49 +0000


On Thursday 10 February, Harri Pasanen wrote:

The problem is caused by a bug in omniORBpy's CosNaming module. When
you import it, it causes a dummy _GlobalIDL module to be created. This
means that when you import _GlobalIDL, it doesn't actually get the
Echo stubs.

The fixed CosNaming module is in CVS. A temporary fix is to import
_GlobalIDL before CosNaming.

Although that is the cause of your problem there are a few things
which are potential problems in your code. I'll go through it,
explaining what's going on and might go wrong.

> #!/usr/bin/env python
> 
> import sys, string
> 
> # set naming service location explicitly here
> sys.argv = [sys.argv[0]] + \
> 	   string.split("-ORBInitialHost localhost -ORBInitialPort 3033")
> 
> # Import the CORBA module
> from omniORB import CORBA
> import CosNaming
> 
> # Import the stubs for the Example module -- not used directly,
> side-effect magic ???
> import _GlobalIDL

Apart from the fact that it wasn't working, this is indeed side-effect
magic. It means that the ORB has seen the definitions for the Echo
interface, so it knows how to create Echo object references.

> # Initialise the ORB
> orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID)
> 
> def getObjectReference(orb):
>     try:
> 	# Obtain a reference to the root context of the Name service:
> 	# Note that for Python we don't need to narrow ???
> 	rootContext = orb.resolve_initial_references("NameService")

You don't _need_ to narrow in this case, but you should anyway.
resolve_initial_references() is declared to return a plain
CORBA::Object. What it actually gets happens to be a
CosNaming::NamingContext. Since you imported the CosNaming module, it
knows about that interface, and it can create an object reference to
it.

However, suppose that resolve_initial_references() actually returned
an object with an interface derived from CosNaming::NamingContext
(which it would do if the NameService supported the Interoperable
Naming Service). Now, the object reference would be to a
NamingContextExt object which the ORB doesn't know about. The only
thing it can do is create a plain CORBA.Object.

So, you should always narrow an object reference you receive from a
function which is declared to return CORBA::Object, just in case you
receive something unexpected which is derived from what you expected.

The same is not true if you have IDL like

interface I {
  ...
};
interface J {
  I give_me_an_I();
};

When you call give_me_an_I(), you don't have to narrow the result,
even if you actually get something derived from I that you don't know
about. This is because the ORB knows you were expecting an I. The
first time you contact the object, the ORB checks that it is really an
I.

Anyway, on with the code.

> 	if CORBA.is_nil(rootContext):
> 	    print "Failed to narrow naming context." 
> 	    return CORBA.Object._nil()
> 	
>     except: # CORBA.ORB.InvalidName:  -- InvalidName not found ???
> 	print "Service required is invalid [does not exist]."
> 	return CORBA.Object._nil()

I haven't got around to implementing the InvalidName exception yet.
It's on my list of things to do. In the mean time, you get
CORBA.BAD_PARAM if the name is invalid.

>     # Create a name object, containing the name test/context:
>     nc = CosNaming.NameComponent
>     name = [nc("test", "my_context"), nc("Echo", "Object")]
> 
>     try: 
> 	# Resolve the name to an object reference, and assign the reference 
> 	# returned to a CORBA.Object:
> 	obj = rootContext.resolve(name)
>     except CosNaming.NamingContext.NotFound:
> 	# This exception is thrown if any of the components of the
> 	# path [contexts or the object] aren't found:
> 	print  "Context not found." 
> 	return CORBA.Object._nil()
>     except CORBA.COMM_FAILURE:
> 	print "Caught system exception COMM_FAILURE, unable to contact the "
> 	print "naming service."
> 	return CORBA.Object._nil()
>     except omniORB.fatalException:
> 	print "fatalException"
> 	sys.exit(-1)

omniORB.fatalException doesn't exist, and isn't ever likely to in the
Python mapping. If something fatal happens in the C++ bit of the ORB,
it's highly unlikely that it will be possible to return to Python
code.

>     except:
> 	print "Caught a system exception while using the naming service."
> 	return CORBA.Object._nil()
>     return obj
> # end getObjectReference(orb)
> 
> # Contact the naming service
> object = getObjectReference(orb)  # this returns omniORB.CORBA.Object
> instance

With the fixed CosNaming module, you will get a
_GlobalIDL._objref_Echo here. However, everything I said before about
narrowing applies again, and you should narrow just in case you
receive something inherited from Echo.

Cheers,

Duncan.

-- 
 -- Duncan Grisby  \  Research Engineer  --
  -- AT&T Laboratories Cambridge          --
   -- http://www.uk.research.att.com/~dpg1 --