Declaring JNDI names in JBoss 3.0
This section deals with the JBoss implementation and usage of JNDI, the J2EE lookup system.
Setting context properties
Within a J2EE environment, it is really easy to get the needed initial context by simple calling
the constructor:
import javax.naming.*;
InitialContext ctx = new InitialContext();
This is possible, because the required setup is done by JBoss itself. For an external client
program, it is not as easy as this, but still quite simple. You need to supply the needed
information like the provider URL and the context factory by one of several means:
A map, given in the constructor call
Properties set in the system properties
A properties file found in the class path.
Using the first method, you introduce hard-coded environment values in your code (but keep
all together):
import javax.naming.*;
// hard-coded JNDI settings in the application
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "jnp://adrasteia:1099");
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
InitialContext ctx = new InitialContext(env);
The second method uses the -D<name>=<value> command-line specifier to set some
of the JNDI values, which are better collected in a properties file.
This is what the third method is:
# file jndi.properties
# must be found in the class path of JBoss
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://adrasteia:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
The third way is normally the best, yielding the most decoupling of code and setup.
JNDI ENCs
Each application component of a J2EE application has an individual enterprise naming
context or ENC, providing space for setup-constants, distributed objects and whatever-you-need.
The ENC is got with code like this:
import javax.naming.*;
InitialContext ctx = new InitialContext();
Context env = ctx.lookup("java:comp/env");
The ENC is normaly local for each component, but there are different types of ENCs with different
visibilities:
-
java:comp is the component-specific indivual ENC. This ENC is what
you normally use in your J2EE application.
-
java: is an ENC which is visible only in the JBoss VM. It holds references
to objects which are only senseful in the JBoss environment, like data sources or other
ressources.
- The other ENCs are visible from remote client and can hold references to EJB home interfaces.
Environment entries kept in an ENC
One usage of the individual ENC is to store setup constants there which can then be looked
up by the application component. You specify these settings in the regular files web.xml:
<web-app>
<env-entry>
<description>...</description>
<env-entry-name>MaxValue<env-entry-name>
<env-entry-type>java.lang.Float</env-entry-type>
<env-entry-value>45.4</env-entry-value>
</env-entry>
</web-app>
and, analogously, in the file ejb-jar.xml:
<ejb-jar>
<enterprise-beans>
<session>
<env-entry>
<description>...</description>
<env-entry-name>MaxValue<env-entry-name>
<env-entry-type>java.lang.Float</env-entry-type>
<env-entry-value>45.4</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
The name is relative to java:comp/env, so to get the value, your
application use the following code fragment:
import javax.naming.*;
InitialContext ctx = new InitialContext();
Float oValue = (Float)ctx.lookup("java:comp/env/MaxValue");
float value = oValue.floatValue();
This is possible for all simple data types, using their java.lang. object wrapper
class.
EJB references
EJBs and web components may refer to other EJBs, where symbolic names are used within the
code. These symbolic names are declared in the two configuration files (web.xml
and ejb-jar.xml) nad have to be mapped to the JNDI names of the deployed EJBs,
using vendor-specific tools.
Let's see this in work in the following scenario, wherein an EJB OrderHandler
needs references to two other EJBs. It looking them up with code like this:
import javax.naming.*;
InitialContext ctx = new InitialContext();
PayCheckerHome pchome = (PayCheckerHome)ctx.lookup("java:comp/env/ejb/Paycheck");
CatalogHome chome = (CatalogHome)ctx.lookup("java:comp/env/ejb/Catalog");
It does not know (nor need to know) that the pay checker EJB is outside itw own J2EE application!
The following gives you a graphical overview about the scenario:
Application 1
EJB name: OrderHandler ----------------------------->
JNDI name: OrderHandler java:comp/env/ejb/Paycheck
|
| java:comp/env/ejb/Catalog
v
EJB name: Catalog
JNDI name: general/Products
|
Application 2
EJB name: PayChecker
JNDI name: general/money/Checker
|
In this example, the EJBs Catalog and PayChecker are regarded as general
utility beans, useful for many applications, and therefore mapped under the general
JNDI context. These EJB references are usable by anyone who needs their functionality, even if the
caller is outside the VM (see above). Of course, the OrderHandler is generally
reachable via JNDI, too, but may be somehow secured to be used only within the application 1.
To configure this scenario, we have to write ejb-jar.xml files for each application
and - to resolve the dependencies - also the files jboss.xml. The latter specifies
the JNDI names of the deployed EJBs and can resolve external EJB references as the one to
the paychecker EJB.
For the second application, things are quite easy, so we start with the configuration for this
application. We simply have to specify the JNDI name of the deployed paychecker EJB:
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>PayChecker</ejb-name>
</session>
</enterprise-beans>
</ejb-jar>
|
<jboss>
<enterprise-beans>
<session>
<ejb-name>PayChecker</ejb-name>
<jndi-name>general/money/Checker</jndi-name>
</session>
</enterprise-beans>
</jboss>
|
This is not always a required step, because JBOSS uses the name given in the <ejb-name> element
as the JNDI name, if no JNDI name is specified in a jboss.xml file. So if
we omitt this file, we simply get JNDI names equals to the ejb names for all deployed EJBs.
The first application uses the JNDI name of the deployed paychecker to resolve the external
reference to this EJB. The reference to the catalog EJB is done internally by the
<ejb-link> element (which can only be used for internal references):
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Catalog</ejb-name>
</session>
<session>
<ejb-name>OrderHandler</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/Catalog</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
...
<ejb-link>Catalog</ejb-link>
</ejb-ref>
<ejb-ref>
<ejb-ref-name>ejb/Paycheck</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
...
// no ejb-link here, because target EJB
// is outside this application
</ejb-ref>
</session>
</enterprise-beans>
</ejb-jar>
|
<jboss>
<enterprise-beans>
<session>
<ejb-name>Catalog</ejb-name>
<jndi-name>general/Products</jndi-name>
</session>
<session>
<ejb-name>Orderhandler</ejb-name>
<jndi-name>Orderhandler</jndi-name>
// nothing required, because target EJB
// is in the same application and reachable
// via the ejb-link element
<ejb-ref>
<ejb-ref-name>ejb/Paycheck</ejb-ref-name>
<jndi-name>general/money/Checker</jndi-name>
</ejb-ref>
</session>
</enterprise-beans>
</jboss>
|
Not that it is superflous to specifiy the JNDI name OrderHandler for the
order handler, because it equals the <ejb-name> for this EJB.
Also note that the JNDI names may include hosts to include EJBs, running within another
VM and host! These JNDI names take the form jnp://neria:1099/general/BetterPayChecker.
It is also possible for servlets or JSPs to reference EJBs. As with references from EJBs, these
hve to be declared in the web.xml file and resolved in jboss-web.xml.
If the order handler would be a servlet calling the payment checker EJB and the catalog EJB,
these files would look like this:
<web-app>
<ejb-ref>
<ejb-ref-name>ejb/Catalog</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
...
</ejb-ref>
<ejb-ref>
<ejb-ref-name>ejb/Paycheck</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
...
</ejb-ref>
</web-app>
|
<jboss-web>
<ejb-ref>
<ejb-name>ejb/Catalog</ejb-name>
<jndi-name>general/Products</jndi-name>
</ejb-ref>
<ejb-ref>
<ejb-name>ejb/Paycheck</ejb-name>
<jndi-name>general/money/Checker</jndi-name>
</ejb-ref>
</jboss-web>
|
The reference names are relative to java:comp/env, as they are for references from
within an EJB.
Other JNDI targets
There are other targets for JNDI lookups besides environment entries and EJBs. These include
resource factories and pre-build resources like data sources or JMS queues.
Examples how JNDI is set up for these objects can be found here for
JMS, here for JDBC data sources and here
for mail resources.
Note that there are two types of resource references: references to resource factories
like queue or mail factories, specified in the <resource-ref> elements of
the descriptor files, and the actual resource objects themselves, like the
queues. These are specified in the <resource-env-ref> elements of the
descriptor files.
back to JBoss page
back to toolbox page
|