All,
Many EJB developers who are building applications based on
the EJB 2.x specification seem to be making this (serious)
mistake; and worse do not realize that their code is relying
on an AppServer bug.
The problem itself is a simple one:
When looking up an EJB with local interfaces, developers use
the physical JNDI name of the local enterprise bean in lieu
of the specification defined environment naming context(ENC).
For example: assume a local entity bean with fully qualified
package name: com.mycompany.employee.ejb.EmployeeEjbHome
and any unique local JNDI name (say): EmployeeEjb. This
name could also be the fully qualified class name - which
many seem to prefer.
And the code developers tend to write to lookup this local
bean from a caller (say another EJB / Servlet etc,.) is:
javax.naming.Context jndiContext =
new javax.naming.InitialContext();
Object localRef = jndiContext.lookup("EmployeeEjb");
Unfortunately, the above code is not right. The fact that it
works in your AppServer would be an AppServer bug. Let me
explain:
There are two 'spaces' where you could register resources. One
in the naming service (globally accessible) - and other in the
environment naming context (ENC) of a bean. The ENC is private
to that bean. So, while the underlying implementations are
different, the API (JNDI) used to access both are the same.
The distinguishing factor between the two - is that resources
registered in the ENC begin with the prefix "java:comp/env/".
And the Container 'knows' that any lookup performed with the
"java:comp/env/..." prefix must be routed to the ENC of that
bean, while any other would go to the naming service.
To visualize things, you could think of the ENC as a cute little
naming service for every bean - in which you can register whatever
you want [only that bean] to access.
Depending on the naming service implementation (LDAP | COSNaming
| whatever), calls to the naming service might span processes;
while those to the ENC will [never] do so. Or in other words,
calls to the ENC are always intra-process calls, while the same
[cannot] be guaranteed with the naming service given that it is
AppServer vendor specific.
Since the naming service implementation is vendor specific and
potentially could be either Centralized/Distributed/Homogeneous
across AppServer processes, you cannot register process specific
(or local) resources here. And to make matters complicated
(depending on your view of course), many AppServer vendors offer
your own option (Central/ Distributed/Homogeneous) while setting
up the naming service (at least we - Borland - do) based on your
needs/preferences.
Which brings us to the question - if I cannot use the global JNDI
tree, how do I lookup local EJBs? The answer lies in using the
ENC via EJB Local References entries. EJB Local References are
defined in the deployment descriptor part of the caller bean and
point to the local bean that is the target of the lookup. So
assuming you gave the EJB Local References a name such as
"ejb/EmployeeEjb" and pointed to the Employee local EJB, then
the above local bean can be looked up in the ENC of the caller
by appending the "java:comp/env/" prefix to the string. So, now
your code for looking up a local bean would be:
javax.naming.Context jndiContext =
new javax.naming.InitialContext();
Object localRef = jndiContext.lookup(
"java:comp/env/ejb/EmployeeEjb");
I wonder if developers actually use the above spec compliant
and portable mechanism of performing a lookup on a local bean?
I'd be interested in other thoughts on this. Unfortunately, not
many books/articles I've come across explain these concepts in
sufficient detail.
-krish
===========================================================================
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".