7 Replies Latest reply on Aug 26, 2009 2:07 PM by nadir

    Specifying a local reference to an EJB on WebSphere 7.0

    mrai3

      On WebSphere 7.0 I have an ejb-jar module containing a local interface:


      package test;
       
      @Local
      public interface Ping {
          public String ping();
      }
      



      and a session bean:


      package test;
       
      @Stateless
      public class PingBean implements Ping {
          public String ping() {
              return "pong";
          }
      }
      



      From log I can see this bean is registered into JNDI under shortname 'ejblocal:test.Ping'. From another bean within the same ejb-jar module I can thus access it through


      new InitialContext("").lookup("ejblocal:test.Ping")
      



      My question is how can I make the bean available in JNDI under a name like java:comp/env/test/PingBean. I have tried to configure a local reference in my ejb-jar.xml file like follows:


      <enterprise-beans>
          <session>
              <ejb-name>PingBean</ejb-name>
              <ejb-local-ref>
                  <ejb-ref-name>test/PingBean</ejb-ref-name>
                  <ejb-ref-type>Session</ejb-ref-type>
                  <local-home/>
                  <local>test.Ping</local>
              </ejb-local-ref>
          </session>
      </enterprise-beans>
      



      Unfortunately to no effect. I need to able to specify these kind of names for accessing SLSBs through JNDI from Seam components. That is in Seam configuration file components.xml I would like to specify:


      <core:init jndi-pattern="java:comp/env/test/#{ejbName}" debug="false"/>
      



      Any suggestions would be appreciated.


      Regards,
      Magnus

        • 1. Re: Specifying a local reference to an EJB on WebSphere 7.0
          titou09

          Here the way we have solve this.


          In each SFSB/SLFB, we use @JndiName like this:


          @Stateful
          @Name(<name>)
          @JndiName("ejblocal:<fully qualified interface name>")
          public class <class> implements <interface>, Serializable {
          



          In components.xml


          <core:init jndi-pattern="java:comp/env/#{ejbName}" debug="true" />




          Add a file named "seam-jndi.properties" in the classpath of your web module (don't ask me what'is doing, I got it from the web somewhere..):


          com.ibm.websphere.naming.hostname.normalizer=com.ibm.ws.naming.util.DefaultHostnameNormalizer
          java.naming.factory.initial=com.ibm.websphere.naming.WsnInitialContextFactory
          com.ibm.websphere.naming.name.syntax=jndi
          com.ibm.websphere.naming.namespace.connection=lazy
          com.ibm.ws.naming.ldap.ldapinitctxfactory=com.sun.jndi.ldap.LdapCtxFactory
          com.ibm.websphere.naming.jndicache.cacheobject=populated
          com.ibm.websphere.naming.namespaceroot=defaultroot
          com.ibm.ws.naming.wsn.factory.initial=com.ibm.ws.naming.util.WsnInitCtxFactory
          com.ibm.websphere.naming.jndicache.maxcachelife=0
          com.ibm.websphere.naming.jndicache.maxentrylife=0
          com.ibm.websphere.naming.jndicache.cachename=providerURL
          java.naming.provider.url=corbaloc:rir:/NameServiceServerRoot
          java.naming.factory.url.pkgs=com.ibm.ws.runtime:com.ibm.ws.naming
          


          Then add this in web.xml


            <ejb-local-ref>
                <ejb-ref-name>EjbSynchronizations</ejb-ref-name>
                <ejb-ref-type>Session</ejb-ref-type>
                <local-home></local-home>
                <local>org.jboss.seam.transaction.LocalEjbSynchronizations</local>
             </ejb-local-ref>
          


          And you're done. Works like a charm. No need anymore for any ejb->ejb refs or servlet->ejb refs


          Also if you need to change the timeout for an SFSB, add this PER SFSB in ibm-ejb-jar-ext.xml


             <session name="<SFSB name>"><time-out value="<value>"/></session>


          I currently had opened a PMR to IBM asking how to do this globally for the whole ejb-jar, an ear or for the whole serverm because it's a (small) pain to add this for each SFSB...


          Maybe this could be added as a new chapter in the seam manual on how to configure seam v2.1.2 when run on WebSphere v7.0




          Q: Are you hit by the JBSEAM-3726 bug I opened in November? I have a local patch for it but I'm looking forward for an official correction, allowing us to finally be able to use seam 2.1 with WebSphere v7.0..


          • 2. Re: Specifying a local reference to an EJB on WebSphere 7.0
            mrai3

            Thanks a lot for this information, with help of it I managed to configure SEAM to access local beans through JNDI.


            By specifying JNDI binding for beans in ibm-jar-ejb-bnd.xml I managed to avoid having to specify the qualified names of the beans. Example:


            @JndiName("ejblocal:MyApp/MyBean")
            



            <?xml version="1.0" encoding="UTF-8"?>
            <ejb-jar-bnd
                    xmlns="http://websphere.ibm.com/xml/ns/javaee"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
                    version="1.0">
            
                <session name="MyBean" simple-binding-name="MyApp/MyBean"/>
            </ejb-jar-bnd>
            



            Since I would like to deploy the same code base on JBossAS and WAS, I wonder if there exists a deployment descriptor alternative to the annotation @JndiName? Or maybe I should try to use JNDI bindings that works on both AS?


            So far I have not encountered JBSEAM-3726, but I'm still resolving some other issues, so it might still be waiting for me...


            Installing and Starting my EAR is very slow on WAS 7.0 (fix pack 1) through ISC admin console. All together it takes about 20 minutes (compared to less than a minute on JBossAS 4.2). The application has 120 @Stateless, 280 @Entity, 210 @Name to give a feeling about the size. Are there any validations or similar than can be turned off during test deployment?


            Regards,
            Magnus

            • 3. Re: Specifying a local reference to an EJB on WebSphere 7.0
              nadir
              Huh, thanks. Now i can at least lookup my seam local interfaces..
              Any ideas how to perform a sucessful lookup to get non-seam EJB?
              I have a seam app, a second ear with web and ejb modules, they both run on WAS7. From seam app i try to get the non-seam ejb and invoke the method, but so far without any luck. Both seam and non-seam app run fine when i don't try to integrate them.

              I have added

              <ejb-local-ref>
                    <ejb-ref-name>EjbSynchronizations</ejb-ref-name>
                    <ejb-ref-type>Session</ejb-ref-type>
                    <local-home></local-home>
                    <local>org.jboss.seam.transaction.LocalEjbSynchronizations</local>
                 </ejb-local-ref>

              and registered all ejb's the same way in both apps in web.xml, tried also within ejb-jar.xml, without luck.
              In the non-seam app i cannot use @JndiName...

              I cannot make this work with the java:com/env/project_name/#{ejb} in the components.xml :/
              • 4. Re: Specifying a local reference to an EJB on WebSphere 7.0
                titou09

                Did you tried to use the standard EJB 3 way to do this?, i.e. use the @EJB annotation?


                IMHO this should work without any need to sepcify any web->wjb or ejb->ejb refs


                Maybe you'll have to use tweak some parameters of the @EJB annotation


                The WebSphere information Center should be of great help for this

                • 5. Re: Specifying a local reference to an EJB on WebSphere 7.0
                  nadir
                  Sometimes the easiest solutions are the hardest to find - i'll try it in the moment ;)
                  In the meanwhile i managed to get the object using ejblocal:<fully qualified interface name> as it was a seam component, and it worked almost right... Almost because i was expecting to get an instance of pl.atena.wasEjb.SayHelloBean and i'm getting pl.atena.wasEjb.EJSLocal0SLSayHelloBean_de0102dd whatever that is and comes from... I'll be back after i try to do some @EJB tweaks.
                  • 6. Re: Specifying a local reference to an EJB on WebSphere 7.0
                    nadir
                    According to Websphere Information Center default binding scheme is ejblocal:<fully qualified interface name> so i'm getting the right object.
                    The problem is now with the pl.atena.wasEjb.EJSLocal0SLSayHelloBean_de0102dd -it is some kind of websphere wrapper. It looks like that my problem is not with the lookup as i expected but with the casting to the right thing. pl.atena.wasEjb.EJSLocal0SLSayHelloBean_de0102dd.class.getInterfaces() shows me that this implements the interface that i did a lookup for (pl.atena.wasEjb.SayHello), but instanceof gives me false and (SayHello)pl.atena.wasEjb.EJSLocal0SLSayHelloBean_de0102dd gives ClassCastExeption.

                    I have put the non-seam ejb.jar into the seam app. Any ideas?
                    • 7. Re: Specifying a local reference to an EJB on WebSphere 7.0
                      nadir

                      I finally managed to make it work - it was classloader problem - i had 2 jars with the same class.
                      I solved it by pushing the interface into separate jar file, and made it a shared library bundled to both apps in WAS and it works fine now.