4 Replies Latest reply on Sep 9, 2004 7:18 PM by Darran Lofthouse

    JNDI issues -> POJO cannot locate EJBs correctly

    Leandro Terra Melo Newbie

      Hi,
      i'm facing a very very weird problem.

      Basically, i got POJOs that can locate EJBs and POJOs that cannot locate EJBs. This seems to be a random behaviour.

      Here is.

      I use POJO business objects in a layer between my session façades and my cmps.
      I already have on use case working like this: the façade doesn't make references to other ejbs (neither in ejb-jar.xml nor jboss.xml), as it delegates the work to a business POJO.
      This is business POJO looks for a local interface in the following way.

      partyHouseLocalHome = (PartyHouseLocalHome)ejbHomeFactory.lookupByLocalEJBReference("PartyHouseLocal");
      



      The above code is inside the POJO's constructor. Everything works perfectly fine. I afirm: The façade which delegates to this POJO, which is the PartyIssuesBean, does not have any reference in ejb-jar.xml and jboss.xml to the bean PartyHouseBean, the one i'm looking for in the above code.

      So, today i was creating a new use case and build a very similar archicture -> a session façade that delegates to a POJO.
      I build a brand new session façade that does not reference any other bean in ejb-jar.xml and jboss.xml. This façade delegates to a POJO that, inside it's constructor, look for the following ejbs.

      partyHouseLocalHome = (PartyHouseLocalHome)ejbHomeFactory.lookupByLocalEJBReference("PartyHouseLocal");
      partyNegotiationLocalHome = (PartyNegotiationLocalHome)ejbHomeFactory.lookupByLocalEJBReference("PartyNegotiationLocal");
      



      Here's the weird thing, on the second lookup i get a javax.ejb.NameNotFoundException !!!!
      The lookup for the PartyHouseBean works, but the lookup for the PartyNegotiationBean does not work!!!

      Then, i decided to add a reference (in ejb-jar.xml and jboss.xml) to the PartyNegotiationBean for the Session façade the delegates to this POJO.
      With that, i lookup works fine !!!!
      In other words:
      - When i lookup from this POJO for the PartyHouseBean (as in the code above) i do not need a reference to PartyHouseBean in ejb-jar.xml or jboss.xml for the façade that uses this POJO.

      - When i lookup from this POJO for the PartyNegotiationBean, it only works if a set a reference to PartyNegotiationBean in ejb-jar.xml and jboss.xml for the façade that uses this POJO.

      How weird is that????
      I couldn't see any thing diferent between the code of PartyHouseBean and PartyNegotiationBean..., is there some kind of externalize????


      ejb-jar.xml
      <session >
       <description>[CDATA[]]</description>
      
       <ejb-name>EventPromotion</ejb-name>
      
       <home>ltcmelo.homeinterface.EventPromotionHome</home>
       <remote>ltcmelo.remoteinterface.EventPromotion</remote>
       <local-home>ltcmelo.localhomeinterface.EventPromotionLocalHome</local-home>
       <local>ltcmelo.localinterface.EventPromotionLocal</local>
       <ejb-class>ltcmelo.session.EventPromotionSession</ejb-class>
       <session-type>Stateless</session-type>
       <transaction-type>Container</transaction-type>
      
       <!-- THIS IS THE FACADE THAT DELEGATES TO THE POJO. IN THE POJO I C
       PERFECTLY LOCATE THE PartyHouseBean WITHOUD SETTING A LOCAL REF,
       BUT I CAN ONLY LOCATE THE PartyBean IF I INSERT THIS REFERENCE -->
      
       <ejb-local-ref >
       <ejb-ref-name>ejb/PartyLocal</ejb-ref-name>
       <ejb-ref-type>Entity</ejb-ref-type>
       <local-home>ltcmelo.localhomeinterface.PartyLocalHome</local-home>
       <local>ltcmelo.localinterface.PartyLocal</local>
       <ejb-link>Party</ejb-link>
       </ejb-local-ref>
      
       </session>
      



      jboss.xml
       <session>
       <ejb-name>EventPromotion</ejb-name>
       <jndi-name>EventPromotionBean</jndi-name>
       <local-jndi-name>EventPromotionLocal</local-jndi-name>
      
       <!-- I NEED TO ADD THIS REFERENCE SO MY POJO CAN WORK WITH THE
       PartyBean!!!
       NOTE THAT THE POJO LOCATES THE PartyHouseBean AND I DON'T HAVE
       A REF. TO PartyHouseBean HERE.
       -->
      
       <ejb-local-ref>
       <ejb-ref-name>ejb/PartyLocal</ejb-ref-name>
       <jndi-name>PartyLocal</jndi-name>
       </ejb-local-ref>
      
       <method-attributes>
       </method-attributes>
       </session>
      


      Thanks for any help.

        • 1. Re: JNDI issues -> POJO cannot locate EJBs correctly
          Darran Lofthouse Master

          How sure are you that you have not missed a minor typo in the naming of the bean you are trying to lookup?

          Can you post the full deployment descriptors incase anyone else can see something missing when looking up the other beans.

          • 2. Re: JNDI issues -> POJO cannot locate EJBs correctly
            Leandro Terra Melo Newbie

            first thing: Switch Party to PartyNegotiaion in the xml files.

            My dd is huge (about 30 beans), so i don`t think it`s a good idea to post it.

            Anyway, i think i posted what is important, see.

            EventPromotio is a session façade.
            The event promotion delegates methods to a POJO called PojoEventPromotion. The lookup is done inside this POJO.
            I make two lookups: one for PartyHouse and the other one to PartyNegotiation.
            The lookup for PartyHouse works fine inside this POJO, but the lookup for PartyNegotation only works if i set the refs i mentioned.

            • 3. Re: JNDI issues -> POJO cannot locate EJBs correctly
              Darran Lofthouse Master

              Ok I have been looking around and I think things are clearer now.

              First the fact that POJOs are involved is irrelevant, if a class is called from a session bean the code is running within the session bean, nothing more than that.

              The reason for asking for additional deployment descriptors was to check for any typos that you might have missed, in the past I have spent time on similar issues not noticing one character is different. I now know that this is not your issue here, although the typos in your post proved how easy they are to make.

              I did a search on Google and found the following article: -

              http://www.developer.com/java/ejb/article.php/3069981

              Are you using the EJB connection factory described in the article? This basically means that the code you are looking at is not your lookup code, it is calling a method that modifies the name to perform the lookup.

              home = initialContext.lookup("java:comp/env/ejb/" +
               ejbReferenceComponent);


              The component is being looked up in the java:comp/env namespace, the way to get references into this namespace is by using the ejb-local-ref elements in the session bean definition.

              Also requiring /ejb/ in the name means that the value for <ejb-ref-name> must contain ejb/

              This basically means that for every session bean you need to ejb-ref every other component that it is going to make use of.

              I would reccomend that you scrap the EJB Connection factory or change it so that it is not based on a singleton as the design is flawed and I think that this is leading to your problem.

              Consider the following scenario:-

              You have three session beans A, B, and C

              A has a ref to C. B does not have a ref to anything.

              A is executed first, it calls 'lookupByLocalEJBReference' to obtain a reference to C. As A has a link to C the lookup works and the home interface C is placed in the cache.

              B is then executed and also calls 'lookupByLocalEJBReference' to obtain a reference to C, as the EJB Connection factory is a singleton B uses the same instance as A. The home interface to C is in the cache so is returned to C and everything appears to be working fine.

              How it stops working

              If B was to be called first and attempt to lookup C when the cache is empty the JNDI lookup would be performed. However as B does not contain the link to C the lookup will fail and the NamingException will be thrown.



              Also FYI when adding ejb-ref or ejb-local-ref elements for components defined in the same deployment descriptor you do not need to add anything to the JBoss deployment descriptor, having a <ejb-link> element is enough information for JBoss to find the correct component.

              • 4. Re: JNDI issues -> POJO cannot locate EJBs correctly
                Darran Lofthouse Master

                Some other points that I missed about the 'EJB Connection Factory' earlier.

                1 - The InitialContext that is created is also cached and will relate to the first component that uses the factory, this means that only the ejb-ref values from the first component that uses the factory will be used.

                2 - It is possible that mutliple threads will access the same InitialContext instance concurently, the API says this must not happen as the implementation may not be thread safe.

                3 - Although I don't see it is a major issue the HashMap is synchronized. The EJB spec says that component shouldn't (Or that might be must not) use synchronized code.