I have a ServiceLocator class which has a method that looks up and caches EJB remote home objects. I am occasionally getting a NameNotFoundException from this method telling me that env is not bound when I try doing a lookup using a JNDI name such as "java:comp/env/ejb/MyEjb". What is so odd is that this lookup is working for other JNDI names under java:comp/env, as well as in other cases when using the same JNDI name which causes the exception. It appears that env is bound in some cases but not in others.
This only occurs when I restart my JBoss server after a client has opened an HttpSession. If I also restart the client then the error doesn't occur. The client is a VB application which calls my JBoss web application's Servlets. I'm using JBoss 4.0.1.
Can anyone give me a suggestion as to where I should look for the problem? Thanks in advance.
The ServiceLocator is an object which runs as part of the server, and has its InitalContext bound the first time it's used (this happens in the ServiceLocator Singleton's constructor). The weirdness I'm experiencing is that it completes several lookups successfully before bombing on a lookup which uses the same JNDI name of a lookup that previously worked -- it literally works on one call and then fails on the next. The difference between the times it works and the time it doesn't is that the successful ServiceLocator method invokations originate within Servlets or EJBs and the unsuccessful invokation is made from within a JMX component. Still it's the same ServiceLocator Singleton, with the same internal InitialContext, so it would follow that the InitialContext would never lose a binding, regardless of the type of component that calls the method which does a lookup.
To further illustrate here's the scenario I'm dealing with:
1. The server is started. 2. The client is started. 3. All is well -- the client calls the servlets, which either (a) call the ServiceLocator to get EJBs or (b) invoke JMX services (MBean methods) which call the ServiceLocator to get EJBs. 4. The server is restarted. 5. The client makes a call to a servlet. 6. The servlet makes a call to the ServiceLocator method to get an EJB, and within that EJB the ServiceLocator is again called to get another EJB:
a. Lookup of java:comp/env/ejb/EJBOne is successful b. Lookup of java:comp/env/ejb/EJBTwo is successful
7. The client calls a method on a JMX service (MBean) which internally uses the ServiceLocator to get an EJB. In this case the lookup fails:
c. Lookup of java:comp/env/ejb/EJBThree fails with the following exception stack trace:
javax.naming.NameNotFoundException: env not bound at org.jnp.server.NamingServer.getBinding(NamingServer.java:491) at org.jnp.server.NamingServer.getBinding(NamingServer.java:499) at org.jnp.server.NamingServer.getObject(NamingServer.java:505) at org.jnp.server.NamingServer.lookup(NamingServer.java:249) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:544) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:658) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:520) at javax.naming.InitialContext.lookup(InitialContext.java:351) at com.mycom.util.ServiceLocator.getRemoteHome(ServiceLocator.java:119) etc...
7. The client receives the error and calls another servlet to refresh itself. This servlet looks up the same EJB which the JMX service was trying to lookup, and this time the ServiceLocator has no trouble finding it:
b. Lookup of java:comp/env/ejb/EJBThree is successful
In the ServiceLocator's lookup method I have added debug code to show the HashCode of the InitialContext being used, and in fact it is the same InitialContext being used each time.
What I think is happening is that normally in my application when the JMX components invoke ServiceLocator methods these methods are never doing lookups and are always getting objects previously cached by lookups made by previous ServiceLocator method calls made the Servlets or EJBs. In other words the above scenario is the only time a JMX component is invoking a ServiceLocator method in which the requested object isn't already cached and the lookup actually needs to happen. The "java:comp/env" name is somehow not available within the context of JMX, and hence the lookup fails.
So it appears that within the context of normal (non-JMX) components the JNDI name "java:comp/env" is bound to the InitialContext, but within the context of a JMX component the InitialContext temporarily loses this binding. Is this the really case? If so can someone point me to a reference in which this behavior explained?
The bonehead mistake which was causing the problem: I was always looking up my EJBs with "java:comp/env/" prefixed to the actual JNDI name of the EJB. Now that I've removed this everything works as it should.
If you try to please everybody, your progress is limited by the noisiest fool. And this tiny ad:
a bit of art, as a gift, that will fit in a stocking