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".