Dave,
<vendor>
Actually, I believe the requirement for PRO.narrow in EJB is a mistake.
Let me explain. There are a couple of valid reason for requiring a narrow
in CORBA systems, none of which apply to RMI/EJB systems. Let me work
through the issues, using the following interfaces:
interface A {};
interface B : A {}; // if you prefer, substitute "extends" for ":"
interface C {};
1) In CORBA based systems, there is a repository identifier (repId) which
indicates an object's type. For the types above, the corresponding
repId is: "IDL:A:1.0", "IDL:B:1.0" and "IDL:C:1.0". This repId is embedded
in every CORBA Interoperable Object References (IORs) so that anyone can
read the IOR (from a request, from a reply, from a serialization, etc.) and
know the actual type of the object.
This would have been fine, with everybody putting repIds into their IORs,
except that the CORBA spec was not clear about which repId to put in. The
spec said, essentially, that some repId had to go in there, which corresponded
to the type of the object, but not that the most derived one. So some
vendors chose to put in an untyped repId:
IDL:org.omg/CORBA/Object:1.0
which basically said "this IOR is a CORBA object reference". Of course, we
already knew that, so this was pretty much useless information. (Actually,
I believe the original vendor to do this was implementing CORBA in Smalltalk,
where the CORBA mapping is/was untyped, and it was difficult to keep track
of the original CORBA Object's type. So, they just put into the repId that
they knew.)
Of course, if the spec had been a little more strict (and if the Smalltalk
implementation had been a little more thorough) then we could have relied
on the repId to uniquely identify the instance type. This change to the
CORBA spec could have been made in one of the Java or RMI submissions, and
we could then always know the original type, and provide a stub of that exact
type (and avoid the need for narrowing).
2) Alas, life is not so simple. Even if one knows the correct repId, one
does not always have stubs available of that type. Consider a C++ CORBA
application, where the server implements a B (above), and returns it as a
CORBA::Object, but the client only has at compile time stubs for A. The
ORB runtime can't just instantiate a B stub, since it does not have it.
Furthermore, all that the client-side ORB knows is the repId for the
object, which is "IDL:B:1.0". So, it has no idea that this thing could
be instantiated as an A stub, at least not without going back to the server
to see if the object really is an A. Unfortunately, you don't always
want to go back to the server to determine the "best" type of the object,
since you don't know (at the time of unmarshaling) whether the user even
wants an A instance. They might be happy with a CORBA::Object instance,
or maybe they weren't even going to use the reference. Thus, a second
(and more legitimate need) for the narrow: to go the the server and ask
if a particular IOR "is a" particular repId.
But again, in RMI/EJB based systems, this should not have been an issue.
RMI systems can provide stub downloading, and so it should always be
possible to instantiate a B stub, even if the client does not have
compile time knowledge of B. So even though the user may only want an
A, or maybe an untyped object (which is a java.rmi.Remote, in RMI
parlance), you always get a B stub, and direct casting can be used.
Again, no need for a PRO.narrow.
3) The last issue is a bit more tricky. In CORBA systems, objects can
implement multiple unrelated interfaces simultaneously. This is known
as a "dual interfaces" capability (although it is not limited to two
interfaces). Thus, it is possible to implement a CORBA object which
is both an "A" and a "C" (above) which are completely unrelated types.
Thus, I could call a method which returns an A, and then I should be
able to narrow it to a C. In Java, there is no way to do this this,
to have an instance which is both an A and a C, without having some
type (A+C) which extends both. (Actually, there is now with JDK 1.3
using dynamic proxies, but the RMI/EJB specifications predated this
capability).
But being as there is no way to implement this type of object directly
in Java, there is no way to do this with RMI/EJB, and I don't see that
this last (obscure) CORBA requirement should have forced a PRO.narrow
method to exist in the RMI/EJB world.
In summary, there are three reasons to have a CORBA narrow method.
One of these is obsolete, but the other two remain. However, none of
these issues applies to RMI/EJB based systems, and thus IMO it was a
mistake to require a PRO.narrow.
One last note: two version of our product implemented the "magic
stub" behavior required to avoid narrows. The more recent is the
current release, which has a runtime flag which can be set to avoid
the necessity of using PRO.narrows. We did not enable this flag by
default, as we felt this would encourage users to write non-portable
code, a la WebLogic. But VBJ 4.1 now has this capability, as does
IAS 4.1.
Amusingly, the other version of our product which provided this
capability was Black Widow 1.0, which was the first product I implemented
for this company known variously as Post Modern/Visigenic/Borland/Inprise.
Sadly, we were forced to remove this (then) innovative feature because
we were unable to interoperate with the "technically" spec compliant
Smalltalk ORB mentioned above. Alas, such is progress...
</vendor>
-jkw
Dave Ford wrote:
>
> I understand why, in RMI, you have to use a "cast" with Naming.lookup(..).
> For example:
>
> Foo f = (Foo)Naming.lookup(..)
>
> And I can see why, when coding in straight CORBA, one would use the "narrow"
> method, because narrow(..) is invoked off of an idl2java generated helper
> class, and returns the correct type, without casting.
>
> But, I can't figure out why the javax.rmi.PortableRemoteObject.narrow( )
> even exists. The answer I was given was: "CORBA computability". But that
> makes no sense to me. CORBA compatibility just means the ability to output
> the IIOP wire protocol, right? And you could do that without the
> PortableRemoteObject thing.
>
> The reason I ask, is that I teach Java classes. My students ask me to
> explain why we need to "cast" AND "narrow". I have not been able to give a
> very satisfying answer.
>
> Thanks,
>
> Dave
>
> ===========================================================================
> 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".
===========================================================================
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".