JNDI lookup of EJB3 inside an EAR file on Glassfish
Asked Answered
H

5

6

I have an EAR file with a bunch of JARs in it, and one of these JARs contains Local Session Beans (EJB3). I need to perform a JNDI lookup of these Session Beans from within an unmanaged POJO, also contained in the EAR (and in this case in the same JAR as the EJBs as well). I tried following the Glassfish EJB FAQ, but I keep on receiving a javax.naming.NameNotFoundException no matter what I try.

I am unsure of a few things. Where should I put my ejb-jar.xml (I tried the EARs META-INF as well as the JARs META-INF)? Do I need a sun-ejb-jar.xml? What exactly is ejb-link, what does it do? What could I be doing wrong (my configuration is almost identical to the one given in the FAQ for local lookups)?

I list some of the configuration I tried and the result below:

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <ejb-class>com.test.TestBean</ejb-class>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
      <local>com.test.ITestBean</local>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

Application deploys but JNDI lookup returns null.

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <ejb-class>com.test.TestBean</ejb-class>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
      <local>com.test.ITestBean</local>
      <ejb-link>ITestBean</ejb-link>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

Application doesn't deploy: Unable to determine local business vs. remote business designation for EJB 3.0 ref Unresolved Ejb-Ref ITestBean@jndi.

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <ejb-class>com.test.TestBean</ejb-class>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
      <local>com.test.ITestBean</local>
      <ejb-link>MyJar.jar#ITestBean</ejb-link>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

Application doesn't deploy: Error: Unresolved : MyJar.jar#ITestBean.

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <local>com.test.ITestBean</local>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

Error processing EjbDescriptor

Hornwort answered 6/10, 2009 at 6:53 Comment(2)
"Application doesn't deploy: Unable to determine local business vs. remote business designation for EJB 3.0 ref Unresolved Ejb-Ref ITestBean@jndi." - In this case, your values seem weird. Is com.test.IEntityExtensionDefinitionBean really the local interface for that bean? And why is the name of your own bean and the bean that you are trying to ref the same?Hardhearted
Aah, sorry about that. I tried to tone down the example with easier classes and names, but I missed that one. I updated the question with the correct names. I think I finally got to the bottom of the problem. You mentioned that I have a bean that I want to reference, and my "own" bean, which I didn't understand as I only have one bean. After reading up it seems that I have to register the bean I want to access against another bean. Is this really the only way? What if I want access to the bean from a POJO which isn't managed nor accessed from a managed class?Hornwort
H
0

It isn't possible to perform a JNDI lookup of a bean from a POJO, unless that POJO is called (directly or indirectly) from a managed class (such as a session bean). In other words, the first example won't work while the second one will (assuming MyPOJO is the class that tries to perform a JNDI lookup):

1) UnmanagedClass1 -> UnmanagedClass2 -> UnmanagedClass3 -> MyPOJO
2) ManagedClass -> UnmanagedClass2 -> UnmanagedClass3 -> MyPOJO

Hornwort answered 2/11, 2009 at 11:50 Comment(2)
This is not correct, you definitely can lookup an EJB from a non managed component (injection won't work, but a standard lookup certainly will).Endplay
Hi Pascal, if you know how to get it to work, please tell me as well. None of the tests I tried were successful. Like I said in the answer, the only way I could lookup an EJB from a non managed component was if the call stack included a managed component on a higher level.Hornwort
A
9

You can always also dump on System.out or in a log all the names in the InitialContext.

//Get all the names in the initial context
NamingEnumeration children = initialContext.list("");

while(children.hasMore()) {
    NameClassPair ncPair = (NameClassPair)children.next();
    System.out.print(ncPair.getName() + " (type ");
    System.out.println(ncPair.getClassName() + ")");
  }
}
Anisometropia answered 7/10, 2009 at 10:22 Comment(1)
Thanks for this, it will definitely come in handy.Hornwort
H
2

ejb-jar.xml for your ejb file goes into META-INF (of the EJB-Jar, not of the ear). EJB Refs in the deployment descriptor look something like this:

<ejb-local-ref>
    <ejb-ref-name>EJBName</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local>classname</local>
    <ejb-link>JARName.jar#EJBName</ejb-link>
</ejb-local-ref>

The lookup code looks something like:

Context c = new InitialContext();
return (EJBLocalInterface) c.lookup("java:comp/env/EJBName");

I don't believe that you will need a container specific deployment descriptor (sun-ejb-jar.xml) for this type of lookup.

Hardhearted answered 6/10, 2009 at 13:57 Comment(0)
A
2

I think the EJB 3 Portability Issue blog post should help you.

Anisometropia answered 6/10, 2009 at 14:45 Comment(5)
Yes that is a nice post... thankfully JEE6/EJB3.1 will finally fix this.Hardhearted
Congratulations, elhoim. It is a good ideia standard the JNDI.Anthea
Thanks for the link, I saw it earlier while searching but assumed that it only applied to Remote interface, not Local interfaces like in my case. Does the same apply to Local interfaces?Hornwort
@Ristretto: Names are indeed not standardized for local names either.Anisometropia
Does this mean that I should use the fully qualified name when looking up Local beans?Hornwort
H
0

It isn't possible to perform a JNDI lookup of a bean from a POJO, unless that POJO is called (directly or indirectly) from a managed class (such as a session bean). In other words, the first example won't work while the second one will (assuming MyPOJO is the class that tries to perform a JNDI lookup):

1) UnmanagedClass1 -> UnmanagedClass2 -> UnmanagedClass3 -> MyPOJO
2) ManagedClass -> UnmanagedClass2 -> UnmanagedClass3 -> MyPOJO

Hornwort answered 2/11, 2009 at 11:50 Comment(2)
This is not correct, you definitely can lookup an EJB from a non managed component (injection won't work, but a standard lookup certainly will).Endplay
Hi Pascal, if you know how to get it to work, please tell me as well. None of the tests I tried were successful. Like I said in the answer, the only way I could lookup an EJB from a non managed component was if the call stack included a managed component on a higher level.Hornwort
B
0

I have working on glassfish v2 and when calling JSNI from EJB3 I need only ejb-jar.xml, not sun-ejb-jar.xml

<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee" 
     version = "3.0" 
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">

         <enterprise-beans>

             <session>
                 <ejb-name>TestBean1</ejb-name>
                 <ejb-local-ref>
                    <ejb-ref-name>ejb/TestLocal</ejb-ref-name>
                    <ejb-ref-type>Session</ejb-ref-type>
                    <local>com.clients.TestLocal</local>
                    <mapped-name>ejb/TestLocal</mapped-name>
                </ejb-local-ref>
                 <ejb-local-ref>
                    <ejb-ref-name>ejb/Test2Local</ejb-ref-name>
                    <ejb-ref-type>Session</ejb-ref-type>
                    <local>com.clients.Test2Local</local>
                    <mapped-name>ejb/Test2Local</mapped-name>
                </ejb-local-ref>
              <session>
        <enterprise-beans>

@Stateless(mappedName="ejb/TestLocal")
public class TestBean1 implements TestLocal

@Stateless(mappedName="ejb/Test2Local")
public class TestBean2 implements Test2Local

Calling the service locator inside TestBean1 as

ic.lookup("java:comp/env/ejb/Test2Local");

will return Test2Bean

Bouton answered 26/6, 2010 at 1:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.