![]() |
![]() |
![]() |
|
[BACK] | |
How does an EJB lookup
work?
|
|
Naming is both the blessing and the curse of J2EE. Naming is the general system objects use to get references to each other at runtime. J2EE naming, based on JNDI, is a blessing because it enables dynamically sewing together a complete application at runtime. Different parts of the application can be composed, managed and swapped out on the fly. Naming is also the curse of J2EE in that because everything is configurable, it must all be configured.
A seemingly simple bean lookup travels a path through four configuration files. The purpose of this FAQ is to outline the configuration of a name lookup for a session EJB from a servlet. While the configuration work appears overwhelming at first glance, once you understand the logic it's pretty simple.
The first point to note is that configuration is done in J2EE standards
based files like web.xml
for servlets and ejb-jar.xml
for EJBs. Those files, in turn, have application server specific files
that map names defined in the standard files to the application server's
namespace. As a result, you have the files jonas-ejb-jar.xml
and enhydra-web.xml
.
The next point to note is that the system, like the rest of J2EE, is
designed to differentiate development from deployment. A developer writes
a lookup to a java:/comp/env/ejb/simpleStatelessHome
in the
Java code. At runtime there may be five different simpleStatelessHomes
deployed and registered in different parts of the JNDI namespace. Server
configuration creates the link between the lookup and actual beans. Like
any layer of abstraction, it adds flexibility at the cost of configuration.
The following is based on a simple session bean example. The code for it can be found at:
The example contains the following source files:
presentation/WEB-INF/enhydra-web.xml presentation/WEB-INF/web.xml presentation/WelcomeServlet.java business/META-INF/ejb-jar.xml business/META-INF/jonas-ejb-jar.xml business/SimpleStateless.java business/SimpleStatelessBean.java business/SimpleStatelessHome.java
The servlet gets a reference to the EJB through the following path:
InitialContext
and looks up the bean's
home. The servlet looks up the bean with a reference to java:/comp/env/ejb/simpleStateless
.
Note that the author of the servlet doesn't need to know what class
that maps to or where the class is deployed. The code follows:
/* get the jndi naming context */ initialContext = new InitialContext(); /* look up the home interface for the session bean using jndi */ sessionBeanHome = (SimpleStatelessHome) PortableRemoteObject.narrow( initialContext.lookup("java:comp/env/ejb/simpleStateless"), SimpleStatelessHome.class);The
InitialContext
is looked up without arguments. Most
J2EE servers configure system properties so that any class running in
the server can simply make this call and have it return the appropriate
context. The name simpleStateless
is a little misleading
because you really want a SimpleStatelessHome
. Because
you always access an EJB through the home interface, the EJB container
only returns Homes.
"java:comp/env/ejb/simpleStateless"
is connected to a specific bean in the web.xml
file with
an <ejb-ref>
tag. The code follows:
<ejb-ref> <ejb-ref-name>ejb/simpleStateless</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>simpleStateless.simpleStatelessHome</home> <remote>simpleStateless.simpleStateless</remote> </ejb-ref>Note that name of the bean is
ejb/simpleStateless
. ejb-ref-name
values are defined as being relative to java:comp/env/
.
enhydra-web.xml
configures
the namespace to connect java:comp/env/ejb/simpleStatess
to the actual bean deployed in the rmi naming context as simpleStateless
.
The Enhydra Naming service uses the convention remote
to
refer to the rmi
context. It is necessary because ENS needs
to do some work before forwarding the call to the rmi registry. A direct
call to rmi:xxx
would bypass the ENS provider altogether.
enhydra-web.xml
contains the following:
<?xml version="1.0" encoding="UTF-8"?> <enhydra-web> <ejb-ref> <ejb-ref-name>ejb/simpleStateless</ejb-ref-name> <jndi-name>remote:simpleStatelessHome</jndi-name> </ejb-ref> </enhydra-web>
jonas-ejb-jar.xml
maps the bean defined in ejb-jar.xml
to the actual bean
deployed in the rmi/remote context. The contents of jonas-ejb-jar.xml
follow:
<?xml version="1.0" encoding="UTF-8"?> <jonas-ejb-jar> <jonas-session> <ejb-name>simpleStateless</ejb-name> <jndi-name>remote:simpleStatelessHome</jndi-name> </jonas-session> </jonas-ejb-jar>Note that names in the rmi context must be unique. Deploying this application twice would fail unless the second application used a name unique name like
remote:simpleStatelessHome0
. java:comp/env
do not have a unique requirement because each EJB and web Context is
given its own java:comp/env
namespace.
simpleStateless
in the ejb-jar.xml
file which follows below:
<enterprise-beans> <session> <description>Simple Stateless Session Bean</description> <display-name>SimpleStateless</display-name> <ejb-name>simpleStateless</ejb-name> <home>simpleStateless.SimpleStatelessHome</home> <remote>simpleStateless.SimpleStateless</remote> <ejb-class>simpleStateless.SimpleStatelessBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans>