I have an application deployed at localhost on JBoss 6.0 AS. This application has one remote EJB bean called ExampleEJB. Now I'm trying to code a simple client application that consumes ExampleEJB. This client application will not be deployed at any application server. The idea is to code a simple Java SE client program. I've written the following trying to perform a lookup:
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost:1099");
env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
InitialContext ic = new InitialContext(env);
At this point, I've tried two approaches The first one was to perform a direct lookup like examplified at Java EE 6 Tutorial (http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html):
ExampleEJB exampleEJB = (ExampleEJB) ic.lookup("java:global/myApp/ExampleEJB");
The second attempt was to try to get the JNDI context enviroment and then get the desired bean from this enviroment:
Context envContext = (Context)ic.lookup("java:/comp/env");
envContext.lookup(...)
The problem is that I'm receiving the following exceptions: "javax.naming.NameNotFoundException: global not bound" and "javax.naming.NameNotFoundException: comp not bound" respectively. I'm unable to perform the lookup as desired.
Does someone have a clue?
If you are using java:global/
, then the JNDI name should look like this:
java:global/<application>/<module>/<component>
or
java:global/<ear>/<ejb-jar>/<ejb-name>
where ear is the name of the .ear file, and ejb-jar the name of the EJB .jar file.
If you have both a local and a remote interface, you can differ using this scheme:
java:global/<ear>/<ejb-jar>/<ejb-name>!<interface>
where the interface contains the package and the interface name (example: a.b.c.ExampleEJBRemoteIfc
).
So in your setup: If myApp.ear
contains myEjb.jar
which contains an EJB whose name is ExampleEJB
, then try this JNDI name:
java:global/myApp/myEjb/ExampleEJB
or
java:global/myApp/myEjb/ExampleEJB!a.b.c.ExampleEJBRemoteIfc
Anyway, double check the JNDI name(s) in the JMX console:
http://localhost:8080/jmx-console/
- Click Service=JNDIView
- Operation list: Click invoke button
- Search in that page by the EJB name
As for comp/env vs. global: What is the relationship between java:comp/env and java:global
Ok, I've solved my problem. I've discovered that it is possible to visualize JNDI tree on JBoss by accessing JBoss JMX Management Console (default location at localhost:8080/jmx-console/). Find JNDIView service and invoke list method. By visualizing the JNDI tree I discovered that I was looking for the wrong location. JBoss registered my EJB at:
+- ExampleEar (class: org.jnp.interfaces.NamingContext)
| +- ExampleEJBImpl (class: org.jnp.interfaces.NamingContext)
| | +- remote-br.exemplo.ejb.ExampleEJB (class: Proxy for: br.example.ejb.ExampleEJB)
| | +- remote (class: Proxy for: br.example.ejb.ExampleEJB)
I just modified my code to perform the lookup at:
ExampleEJB exampleEJB = (ExampleEJB) ic.lookup("ExampleEar/ExampleEJBImpl/remote");
and everything went fine.