I'd like to answer to Craigs'question of the "Initial Context" thread about
the narrow.
I change the thread name to avoid any confusion about te content of this
mail ;)

His question was a good one because the narrowing method is usually unknown.

The initial question was:
> > > I am new to EJB.  Could someone explain the following statement(s) in
> > terms
> > > of why
> > > I need to typecast a generic object into the home interface type,
>using
> > the
> > > narrow
> > > method?  What's going on behind the scene here?
> > >
> > > Object boundObject = context.lookup("java:comp/env/ejb/HelloHome");
> > > helloHome = (HelloHome) PortableRemoteObject.narrow(boundObject,
> > > HelloHome.class);

narrow is a CORBAism, which cannot be hidden by the RMI API.
To understand the narrow method, you need to understand how CORBA proxies
are managed.

CORBA proxies
-------------

Example:
        The remote interface B extends the remote interface A
        The remote object implementing the interface B (and so, A)

When you get a remote reference from the naming service, CORBA will create a
Corbae object stub, which is the super class of all the CORBA proxies. If
you try to cast it down to a proxy to B, you will get a ClassCastException.

With CORBA, the proxy may not implemented all the remote interfaces of the
remote object.

So, you have to call the narrow method to create a proxy implementing the
right interface.

The narrow method do the following job:
        1- Test if the proxy implements the requested interface
                If yes, the proxy is only casted-down and returned as-is.
        2- If No, the method test if the remote object implements the
requested interface
                Call the CORBA method is_a which check if the cast is
correct on the server side (IIOP request)
                If not, an exception is send (Corba BAD_PARAM exception)
        3- Create a new proxy
                The narrow method return a new proxy.

Here is an example of the narrow method generated by Javaidl:
  public static A narrow (org.omg.CORBA.Object obj)
  {
    if (obj == null)
      return null;
    else if (obj instanceof A)
      return (A)obj;
    else if (!obj._is_a (id ()))
      throw new org.omg.CORBA.BAD_PARAM ();
    else
    {
      org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
      return new AStub (delegate);
    }
  }
Remark:
        - the Delegate object contains ORB specific code.
        - The AStub do not implements the B interface.

2-- RMI over JRMP
Much simpler. When you lookup an object with RMI, RMI will create a proxy
consistant with the remote object interfaces.
So you don't need narrow at all.

3-- So,
With EJB, look at the following code:
        Object object = context.lookup("ejb.A");
        A a = (A)PortableRemoteObject.narrow(object, A.class);

        With CORBA, the proxy a implements the interface A, but not B !
        With RMI, the proxy a implements A and B, because the remote object
support these interfaces.

        So if you cast down the proxy like that:
        B b = (A)a;
        With CORBA you will get an exception.
        With RMI it will works.

        To make your code portable, you need to write:
        B b = (B)PortableRemoteObject.narrow(a, B.class);
        With CORBA, narrow will create a new proxy, but the proxies a and b
will contains a reference to the same remote object.


Hope this help
Tibo.
http://www.valtech.com

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to