Hi Per,

The reason is that lookups performed via the SessionContext interface are supposed to be relative to java:comp/env. For example:

   public void setSessionContext(SessionContext ejbContext){
       this.thing = (Thing) ejbContext.lookup("myEntry");
   }

and

   public void someMethod() {
       try {
           InitialContext jndiContext = new InitialContext();
this.thing = (Thing) jndiContext.lookup("java:comp/env/ myEntry");
       } catch (NamingException e){
           throw new IllegalArgumentException("myEntry not found");
       }
   }

are exactly the same.

The best public info I could find is the javadoc and a few spec references that show example usages. Unfortunately, the spec never says explicitly say "java:comp/env" is not required.

  Javadoc:
- https://java.sun.com/javaee/5/docs/api/javax/ejb/ EJBContext.html#lookup(java.lang.String)


  EJB 3.0 FR Core Contracts, sections:
    - 3.4.1
    - 3.6.1
    - 16.7.1.2
    - 16.9.1.2
    - 16.10.1.2

Should I be lucky enough to be able to participate again in the next round of EJB specs, I'm definitely going to get this clarified. The intention was to add a service locator style lookup method on the EJBContext to remove the JNDI API cruft people don't like, namely:

   - Remove checked exceptions and the need for try/catch
   - Remove the need for java:comp/env prefix on all names
   - Remove the need for PortableObjectRemote.narrow on bean lookups

Now that said, what I don't recall from the EJB 3.0 EG discussions on this topic if it was ever concluded that use of "java:comp/env" on EJBContext.lookup(..) be explicitly disallowed. There are really only two ways to implement the EJBContext.lookup and depending on which style you use, you get a very different outcome on that question:
   Approach 1:
      public Object lookup(String name){
          try {
              Context ctx = new InitialContext();
              return ctx.lookup("java:comp/env/" + name);
          ...
      }

   Approach 2:
      public Object lookup(String name){
          try {
              Context ctx = new InitialContext();
              ctx = (Context) ctx.lookup("java:comp/env");
              return ctx.lookup(name);
          ...
      }

Both result in the same thing if you perform lookups as shown in the spec (i.e. without java:comp/env), however if you took the second approach then lookups containing the java:comp/env prefix would still work. You can guess which approach we have currently :) There is a third approach actually which is a variant of Approach 2, where the container magically has the "java:comp/env" Context magically available to perform lookups on without having to call to new InitialContext().lookup("java:comp/env") which is very expensive. That's likely what we'll do in the future, though I'm not sure if we will allow java:comp/env lookups.

So I can't give a definitive answer on if java:comp/env lookups per spec intent should be explicitly disallowed, but certainly using that style defeats the purpose of EJBContext.lookup and could cause you to miss out on some potential vendor optimizations around JNDI usage.

Hope this helps!

-David


On Apr 9, 2007, at 1:07 AM, Per Newgro wrote:

Hey all,

i defined a env-entry for my bean in ejb-jar.xml

<session>
  <ejb-name>MyBean</ejb-name>
  <home>my.common.ejb.UseCaseHome</home>
  <remote>my.common.ejb.UseCaseRemote</remote>              
<ejb-class>my.misc.update.ejb.GetLibrariesContentUcEJB</ejb-class>
  <session-type>Stateful</session-type>
  <transaction-type>Bean</transaction-type>
  <resource-ref>
    <res-ref-name>MyDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <resource-ref>
    <res-ref-name>MyDSnoTx</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <env-entry>
    <description>
         The folder of client libraries.
    </description>
    <env-entry-name>libFolder</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>..\the-ext</env-entry-value>
  </env-entry>
</session>

In open-ejb-xml it's simply defined as

<ejb-deployment ejb-name="GetLibrariesContentUC"
  deployment-id="GetLibrariesContentUC" container-id="Default Stateful
  Container">
  <resource-link res-ref-name="MyDS" res-id="MyNyxDS"/>
  <resource-link res-ref-name="MyDSnoTx" res-id="MyDSnoTx"/>
</ejb-deployment>

But if i try to access the env entry in the bean i get an
javax.naming.NameNotFoundException: Name "java:comp/env/java:comp/ env" not
found.

String extFolderName = getEnvEntry("libFolder");

/**
 * Get an environment entry for bean
 * @param key of env-entry
 * @return Object the defined parameter
 * @throws CoreException occured
 */
@SuppressWarnings("unchecked")
private <T> T getEnvEntry(String key) throws CoreException {
  SessionContext ictx = getSessionContext();
  Context myenv = (Context) ictx.lookup("java:comp/env");
  T result = null;
  try {
    result = (T) myenv.lookup(key);
  } catch (NamingException e) {
    handleRTException(e);
  }
  return result;
}

Complete exception is
my.common.exception.DataException: javax.naming.NameNotFoundException:
Name "java:comp/env/java:comp/env" not found.?
        at
my.server.ejb.AbstractUseCaseEJB.handleRTException (AbstractUseCaseEJB.java:396) at my.server.ejb.AbstractUseCaseEJB.start (AbstractUseCaseEJB.java:157)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at
org.apache.openejb.core.interceptor.ReflectionInvocationContext $Invocation.invoke(ReflectionInvocationContext.java:136)
        at
org.apache.openejb.core.interceptor.ReflectionInvocationContext.procee d(ReflectionInvocationContext.java:119)
        at
org.apache.openejb.core.interceptor.InterceptorStack.invoke (InterceptorStack.java:72)
        at
org.apache.openejb.core.stateful.StatefulContainer._invoke (StatefulContainer.java:413)
        at
org.apache.openejb.core.stateful.StatefulContainer.businessMethod (StatefulContainer.java:375)
        at
org.apache.openejb.core.stateful.StatefulContainer.invoke (StatefulContainer.java:250)
        at
org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod (EjbObjectProxyHandler.java:191)
        at
org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke (EjbObjectProxyHandler.java:61)
        at
org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke (BaseEjbProxyHandler.java:182)
        at
org.apache.openejb.util.proxy.Jdk13InvocationHandler.invoke (Jdk13InvocationHandler.java:49)
        at $Proxy34.start(Unknown Source)
at my.client.ejb.UseCaseDelegate.start(UseCaseDelegate.java: 108)
        at
my.misc.update.frontend.UpdateUcExecutor.updatedLibraries (UpdateUcExecutor.java:105)
        at
my.misc.update.frontend.LibrariesUpdateStartup.execute (LibrariesUpdateStartup.java:52) at my.client.startup.StartupBot.runStartups(StartupBot.java: 87) at my.client.startup.StartupBot.executeStartups (StartupBot.java:55)
        at my.client.swing.Main.executeInitialization(Main.java:46)
        at my.client.swing.Main.<init>(Main.java:35)
        at my.client.swing.Main.main(Main.java:68)
Caused by: java.lang.IllegalArgumentException:
javax.naming.NameNotFoundException: Name "java:comp/env/java:comp/ env" not
found.
at org.apache.openejb.core.BaseContext.lookup (BaseContext.java:118)
        at
my.server.ejb.AbstractUseCaseEJB.getEnvEntry (AbstractUseCaseEJB.java:497)
        at
my.server.ejb.AbstractUseCaseEJB.getEnvEntryFolderName (AbstractUseCaseEJB.java:231)
        at
my.misc.update.ejb.LibrariesUcEJBBase.run(LibrariesUcEJBBase.java:55)
at my.server.ejb.AbstractUseCaseEJB.start (AbstractUseCaseEJB.java:182) at my.server.ejb.AbstractUseCaseEJB.start (AbstractUseCaseEJB.java:154)
        ... 23 more
Caused by: javax.naming.NameNotFoundException:
Name "java:comp/env/java:comp/env" not found.
        at
org.apache.openejb.core.ivm.naming.IvmContext.federate (IvmContext.java:172)
        at
org.apache.openejb.core.ivm.naming.IvmContext.lookup (IvmContext.java:129)
        at javax.naming.InitialContext.lookup(InitialContext.java:351)
at org.apache.openejb.core.BaseContext.lookup (BaseContext.java:116)
        ... 28 more

Do i have to add something? Or is my method invalid? Maybe i have to check
first if an empty lookup gives me the result?

Thanks for help
Cheers
Per


Reply via email to