11 Replies Latest reply on Dec 14, 2011 1:55 PM by edwardpig

    JNDI binding and NameNotFoundException

    edwardpig

      I'm an EJB-newbie, so please bear with me.  I'm running JBoss 5.1.0, and I'm trying to define/deploy/access a stateless session bean.  It's my understanding that JBoss 5.1.0 conforms to EJB 3.0, and so I can do the whole thing with annotations, without the need for a ejb-jar.xml or jboss.xml file.

       

      After much Googling, I have tried a number of different ways to do things, most recently the following.  In my bean class, I added a no-args constructor and the following annotation and interface:

       

      {code}

      @Stateless

      public class ScoreComputer implements IScoreComputer

      {code}

       

      I defined an IScoreComputer class which declares the methods I want to have available, and put the following annotation on it:

       

      {code}

      @Local

      public interface IScoreComputer

      {code}

       

      In my server code, I try to obtain a reference to my ScoreComputer as follows:

       

      {code}

      IScoreComputer computer;

      InitialContext ejbContext = new InitialContext();

      computer = (IScoreComputer)ejbContext.lookup("ScoreComputer/local");

      {code}

       

      When this code executes, a NameNotFoundException is thrown with the message 'IScoreComputer not bound'.  I know I'm not doing the JNDI binding correctly, because I've looked in the JMX console for JBoss, and no binding is listed containing the string 'Score'.  But try as I might, I am unable to find instructions telling me the correct way to do the binding.

       

      I am using the Spring DispatcherServlet as my servlet, and for a while I thought that might be what is causing the problem, and it may well be.  But I replaced that in my web.xml with a simple class which extends HttpServlet, and got the same behavior.  I have also tried injecting my bean using the @EJB annotation, e.g.

       

      {code}

      @EJB

      protected IScoreComputer computer;

      {code}

       

      but that fails when JBoss attempts to deploy the .ear file, with a message "Resolution should not happen via injection container".

        • 1. Re: JNDI binding and NameNotFoundException
          wdfink

          Do you have checked whether your ScoreComputer is deployed and bound correct?

          You should see some lines in the logfile what the JNDI names are.

          If unsure just start the server without you application and copy your ear to deploy after the server is up.

          • 2. Re: JNDI binding and NameNotFoundException
            jaikiran

            Also, what does your application packaging look like? Where are those EJBs placed and how do you deploy the application?

            • 3. Re: JNDI binding and NameNotFoundException
              edwardpig

              @Wolf-Dieter: I know my .ear is deployed, because I can access the HTML pages I put in it.  When I make changes and redeploy, I see the changes.  User interaction is as expected until execution hits the point where I'm trying to access the ScoreComputer bean.  I know the JNDI binding is not correct because I don't see my bean listed anywhere in the JMX console.

               

              @jaikiran: Here is the directory structure in my development directory:

               

              ${basedir}

                |--src (standard Java source directory structure)

                |--build

                |--dist

                |--lib

                |--webinf

                    |--static (contains .css, .js)

                    |--velocity (contains Velocity .vm templates)

                    |--application.xml

                    |--scpoc-servlet.xml

                    |--web.xml

                |--build.xml

               

              And here is my build.xml file:

               

              {code:xml}<?xml version="1.0"?>

              <project name="scpoc" basedir="." default="ear">

               

                  <property name="build" value="${basedir}/build" />

                  <property name="content" value="${basedir}/content" />

                  <property name="deployDir" value="D:/Applications/jboss-5.1.0.GA/server/default/deploy" />

                  <property name="dist" value="${basedir}/dist" />

                  <property name="jboss_lib" value="D:/Applications/jboss-5.1.0.GA/common/lib" />

                  <property name="lib" value="${basedir}/lib" />

                  <property name="src" value="${basedir}/src" />

                  <property name="webinf" value="${basedir}/webinf" />

                  <property name="version" value="0.1" />

               

                  <path id="build.classpath">

                      <fileset dir="${jboss_lib}" includes="**/*.jar" />

                      <fileset dir="${lib}" includes="**/*.jar" />

                  </path>

               

                  <target name="clean">

                      <delete dir="${build}" />

                      <delete dir="${dist}" />

                  </target>

               

                  <target name="init">

                     <tstamp />

                      <mkdir dir="${build}" />

                      <mkdir dir="${dist}" />

                  </target>

               

                  <target name="compile" depends="init">

                      <javac srcdir="${src}" destdir="${build}" optimize="on">

                          <classpath refid="build.classpath" />

                      </javac>

                  </target>

               

                  <target name="war" depends="compile">

                      <war destfile="${dist}/${ant.project.name}.war" webxml="${webinf}/web.xml">

                          <lib dir="${lib}" />

                          <classes dir="${build}" />

                          <webinf dir="${webinf}">

                              <exclude name="web.xml" />

                              <exclude name="application.xml" />

                          </webinf>

                      </war>

                  </target>

               

                  <target name="ear" depends="war">

                      <ear destfile="${dist}/${ant.project.name}-${version}.ear" appxml="${webinf}/application.xml">

                          <fileset dir="${dist}" includes="*.war" />

                      </ear>

                  </target>

               

                  <target name="deploy" depends="ear">

                      <copy todir="${deployDir}">

                          <fileset dir="${dist}" includes="*.ear" />

                      </copy>

                  </target>

              </project>{code}

               

              I build the ear and deploy it to the JBoss 'default/deploy' directory.  Thanks.

              • 4. Re: JNDI binding and NameNotFoundException
                wdfink

                I think Jakiran meant the structure of your EAR and application.xml.

                 

                I'm not sure but I suppose that you pack the ejb classes into the web application and I'm unsure whether it is picked up here.

                 

                I prefere to add a ejb.jar to the ear and add the element module.ear to the application.xml

                • 5. Re: JNDI binding and NameNotFoundException
                  edwardpig

                  I would have thought that showing my build.xml would answer the question about how my EAR is structured.  And I was never aware that I needed to include a file called ejb.jar anywhere.

                   

                  Perhaps the question I should really be asking is: where can I find a good tutorial about these topics?  I have been jumping from one 'Getting Started with EJB' site to another, and clearly the information I'm getting is incomplete.  Compounding the problem is that there are still a lot of old EJB 2.x sites out there, providing what was accurate, but now outdated information.

                  • 6. Re: JNDI binding and NameNotFoundException
                    wdfink

                    I use jboss.org examples or http://docs.oracle.com/javaee/

                     

                    BTW the file must not named ejb.jar, the file that include your ejb's must be added to the META-INF/application.xml

                    like this:

                    <module><ejb>myejb.jar</ejb></module>

                    <module><java|web ....

                    1 of 1 people found this helpful
                    • 7. Re: JNDI binding and NameNotFoundException
                      edwardpig

                      Okay, it looks like my error was in believing that JBoss 5.1.0 was EJB 3.0 compliant.  I added the jar file and application.xml markup per Wolf-Dieter's suggestion, but then I got an IllegalStateException stating "Null beannMetaData".

                       

                      I tried doing more things with annotations, but the error never went away.  So I eventually gave up and wrote an ejb-jar.xml file.  That appears to have satisfied JBoss' need for metadata, but now I'm getting all kinds of warnings about EJB spec violations. because my bean doesn't define the require ejbCreate method, the methods defined in my interface don't throw java.rmi.RemoteException, etc.

                       

                      So either the inclusion of the ejb-jar.xml has caused JBoss to treat my bean as an EJB 2.0 bean, or there's some configuration tweak I don't know about to tell JBoss that I'd like to use the 3.0 spec and annotations, rather than implementing EJB interfaces on my business beans, etc.

                       

                      Any help there?

                      • 8. Re: JNDI binding and NameNotFoundException
                        wdfink

                        It must be still a package or coding problem.

                        I use ejb3 without any descriptor except application.xml

                         

                        The structure is

                        META-INF/MANIFEST.MF

                        META-INF/application.xml

                        ejb.jar                 # ejb3 stateless session bean and interface

                        persistence.jar     # JPA entity used by the SLSB

                         

                        application.xml:

                        <application>

                            <display-name/>

                            <description/>

                             <module><ejb>ejb.jar</ejb></module>

                            <module><java>persistence.jar</java></module>

                        </application>

                         

                        In my example the ejb.jar include Bean and Interface. If you have a seperate interface jar you can add it like the persistence.jar.

                        1 of 1 people found this helpful
                        • 9. Re: JNDI binding and NameNotFoundException
                          edwardpig

                          Okay, I finally got it figured out.  There were two missing pieces when I originally posted this 2 days ago.

                           

                          One, I didn't know I needed to package my bean classes in a separate jar and declare it in my application.xml.  So thanks to Wolf-Dieter for that bit of information.

                           

                          Two, when attempting to access the bean from my code, I was using InitialContext.lookup() and supplying a string of "<ear-name>/<bean-name>/local".  I didn't realize that I had to supply the full ear file name, including the version.  That seems a bit klunky to me, to hard-code a version ID in my Java code.  But once I got past the first hurdle of declaring my EJB jar file in the application XML, I was able to see the name JBoss was using to bind my bean to JNDI, and I saw that indeed the version ID was there.

                           

                          So once I specified the JNDI name correctly, everything worked.  Thanks.

                          • 10. Re: JNDI binding and NameNotFoundException
                            wdfink

                            You should use '@EJB MyBeanLocal xxx;' instead of code a lookup, you are using EJB3 with injection.

                            In this case you don't have to know the JNDI name.

                            • 11. Re: JNDI binding and NameNotFoundException
                              edwardpig

                              That was one of the first things I tried.  I kept getting an error at deployment:

                               

                              'Resolution should not happen via injection container'

                               

                              I suppose this was happening as a consequence of other things I was doing wrong.  Now I no longer see that message.  However, I am using Spring MVC to handle requests, and NOW I get an error message from Spring because it knows nothing about the bean declaraion.