10 Replies Latest reply on Jul 1, 2010 9:22 AM by Sanjeev Sirigere

    Seam Injecting EJB3 in Websphere.

    rkpraveenp Newbie

      Hello All,


      I am new to Seam and followed the seam gen tutorial to get the seam project on Websphere with EJB3 Feature Pack (6.1.0.13).  The project EAR deployed without errors. I now have Pojo's annotated as Seam components along with @Stateless annotation so that they are EJB3.


      Once I annotate pojos as EJB3, Websphere is not able to inject the EJB3 correctly. 


      I have both the remote and local interfaces for the bean. I have written a java client to test that EJB3 is working fine and it has no issues getting the EJB3 and invoking methods.


      In component XML, I have tried to give the jndiPattern as per the JNDI names generated by Websphere for the EJB3 beans, but without much success.


      Can Seam inject EJB3 on Websphere?  What am I missing in the above?


      Thanks for your help.

        • 1. Re: Seam Injecting EJB3 in Websphere.
          Jay Balunas Novice

          Hello,


          Take a look and compare with the jee5 example in the reference guide.  WebSphere's EJB3 injection and scoping is a little strange.  You need to do the trick in the web.xml so that Websphere will make the EJBs available to the application.


          If that does not work can you post your web.xml, and components.xml?  Also post the errors you see.


          Thanks,
          Jay

          • 2. Re: Seam Injecting EJB3 in Websphere.
            rkpraveenp Newbie

            Hello,


            Thank you for the response.  The following is what I am trying:
            Through seam, trying to inject a stateless session bean into another stateless session bean using the \@In annotation. 


            Both EJBs are in the same Jar file. I am invoking SessionBeanB.methodB through a standalone java client from the command line (using JDK1.5.0 update 14) by getting the SessionBeanB using JNDI name through iiop.  I have also done the classloader settings in WAS as per documentation and followed other steps in http://in.relation.to/Bloggers/WebSphereRunningSeamsJEE5BookingExample


            The code sample, web.xml, component xml and error are as follows.


            Java Code


            
            com.test.SessionBeanA.java
            
            @Name("sessionBeanA")
            
            @Scope(ScopeType.STATELESS)
            
            @Stateless
            
            public class SessionBeanA implements iARemote, iALocal{
            
                public void methodA(){}
            
            }
            
            


            Note: iARemote interface is annotated as \@Remote and iALocal interface is annotated as \@Local.


            
            com.test.SessionBeanB.java
            
            @Name("sessionBeanB")
            
            @Scope(ScopeType.STATELESS)
            
            @Stateless
            
            //Note: iBRemote interface is annotated as @Remote and iBLocal interface is annotated as @Local
            
            public class SessionBeanB implements iBRemote, iBLocal{
            
                @In(create = true)
            
                iALocal sessionBeanA;
            
            
                //I have also tried the following:
            
                //@In(create = true)
            
                //SessionBeanA sessionBeanA
            
            
                public void methodB(){
            
                    sessionBeanA.methodA();
            
                }
            
            }
            
            



            Component.xml 


            
            <core:init debug="true" jndi-pattern="java:comp/env/TestApp/#{ejbName}"/>
            
            <core:manager concurrent-request-timeout="500" 
            
                             conversation-timeout="120000" 
            
                             conversation-id-parameter="cid"/>
            
            <persistence:managed-persistence-context name="em"
            
                                     auto-create="true"
            
                                    entity-manager-factory="#{Test_EMFactory}"/>
            
            <persistence:entity-manager-factory name="Test_EMFactory" persistence-unit-name="TestUnit"/>      
            
            <transaction:ejb-transaction />   
            
            



            Note: The entity manager is getting created and working fine.


            Web.xml 


            
            <ejb-local-ref>       
            
                    <ejb-ref-name>TestApp/SessionBeanA</ejb-ref-name>       
            
                    <ejb-ref-type>Session</ejb-ref-type>      
            
                    <local-home></local-home>           
            
                    <local>com.test.iALocal</local>       
            
            </ejb-local-ref>
            
            



            Note: Web.xml is part of the standard web module which got created using seam-gen.


            Error (in Websphere log)


            
            ExceptionUtil E   CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "methodB" on bean "BeanId(TestApp#TestApp.jar#SessaionBeanA, null)". Exception data: org.jboss.seam.InstantiationException: Could not instantiate Seam component: sessionBeanA
            
                    at org.jboss.seam.Component.newInstance(Component.java:1970)
            
                    at org.jboss.seam.Component.getInstance(Component.java:1873)
            
                    at org.jboss.seam.Component.getInstance(Component.java:1840)
            
                    at org.jboss.seam.Component.getInstanceInAllNamespaces(Component.java:2182)
            
                    at org.jboss.seam.Component.getValueToInject(Component.java:2134)
            
            Caused by: javax.naming.NameNotFoundException: Name comp/env/TestApp not found in context "java:".
            
                    at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.java:1767)
            
                    at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.java:1083)
            
                    at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.java:991)
            
                    at com.ibm.ws.naming.urlbase.UrlContextImpl.lookup(UrlContextImpl.java:1263)
            
                    at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:384)
            
                    at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:204)
            
                    at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:144)
            
                    at javax.naming.InitialContext.lookup(InitialContext.java:363)
            
                    at org.jboss.seam.Component.instantiateSessionBean(Component.java:1287)
            
                    at org.jboss.seam.Component.instantiate(Component.java:1273)
            
                    at org.jboss.seam.Component.newInstance(Component.java:1966)
            
                    ...36 more
            
            

            • 3. Re: Seam Injecting EJB3 in Websphere.
              Jay Balunas Novice

              The error that you are seeing is not that it can't find the bean.  It is that it can't find your app TestApp.  Although these can be related. 


              Here are some questions/suggestions:



              • Do you have any other entries in your web.xml?




              • When you deploy do you see all of the beans from the web.xml listed on the Map EJB references to beans page?




              • On the Map EJB references to beans do you select Allow EJB reference targets to resolve automatically?



              The core problem here is that the WAR is not provided/linked to the EJB context in the EAR.  That is why your command line client can get to the EJB but your WAR can't.  The steps during deployment and in the web.xml are key to this.   


              This was one of the trickier issues to work out.  Take a look at the reference guide because it contains more information about the the apps than the getting started guide.

              • 4. Re: Seam Injecting EJB3 in Websphere.
                rkpraveenp Newbie

                Hello,


                With regards to your questions,


                * Do you have any other entries in your web.xml?
                    No.  Nothing outside of what seam-gen puts in and what is in the guides.


                * When you deploy do you see all of the beans from the web.xml listed on the Map EJB references to beans page?
                    Yes, they are listed as per the web.xml
                * On the Map EJB references to beans do you select Allow EJB reference targets to resolve automatically?
                    Yes.  I do select this option.


                One observation I have is that in the Websphere log, the beans get deployed under the following JNDI names:


                Remote: ‘ejb/TestApp/TestApp.jar/SessionBeanA#com.test.iARemote’ or ‘com.test.iARemote’


                Local: ‘ejblocal:TestApp/TestApp.jar/SessionBeanA#com.test.iALocal’ or ‘ejblocal:com.test.iALocal’


                So, I am not clear on how they can be accessed using the jndi-pattern given in the component XML.


                Am also going through all the settings and the guide again to make sure that I have not missed anything.


                Thank you.

                • 5. Re: Seam Injecting EJB3 in Websphere.
                  Sanjeev Sirigere Newbie

                  Hi,
                  I was also working on getting Seam to work with EJB 3 components on Websphere 6.1.0.17 with EJB3 fp + webservice fp. I am using the Seam version jboss-seam-2.0.1.GA. Initially my approach was to get the Booking sample to work. After sometime, I realized that, instructions to configure were not complete and could not get it working.


                  So I started with simple Seam-gen project and customized it for Websphere.. With that and my changes, I could able to get the seam injection working. Following are my observations.


                  Configuring Seam


                  If Seam component is a EJB3 component, then seam binds the component to a JNDI name. Seam resolves the JNDI name of the component by looking at the below configuration in the components.xml file.


                  components.xml


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



                  In the above example, seam is configured to bind the ejb component to a logical JNDI name. at runtime, seam will replace the string #{ejbName} with the actual component name.


                  Configuring the deployment descriptor


                  To bind the ejb component com.somepackage.ejbs.SeamEJB to jndi name, java:comp/env/Websphere_seam/SeamEJB, add the below configuration to the EJB component, which needs the SeamEJB seam component to be injected.


                  ejb-jar.xml


                  
                  <?xml version="1.0" encoding="UTF-8"?>
                  
                  <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
                  
                          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"
                  
                          version="3.0">
                  
                  <enterprise-beans>
                  
                                  <session>
                  
                                          <ejb-name>EJB3</ejb-name>
                  
                                          <ejb-local-ref>
                  
                                                  <ejb-ref-name>Websphere_seam/SeamEJB</ejb-ref-name>
                  
                                                  <local>com.somepackage.ejbs.SeamEJBInterface</local>
                  
                                          </ejb-local-ref>
                  
                                  </session>
                  
                          </enterprise-beans>
                  
                          <interceptors>
                  
                                  <interceptor>
                  
                                          <interceptor-class>
                  
                                                  org.jboss.seam.ejb.SeamInterceptor
                  
                                          </interceptor-class>
                  
                                  </interceptor>
                  
                          </interceptors>
                  
                  
                          <assembly-descriptor>
                  
                                  <interceptor-binding>
                  
                                          <ejb-name>*</ejb-name>
                  
                                          <interceptor-class>
                  
                                                  org.jboss.seam.ejb.SeamInterceptor
                  
                                          </interceptor-class>
                  
                                  </interceptor-binding>
                  
                          </assembly-descriptor>
                  
                  </ejb-jar>
                  
                  


                  Please use ejb-local-ref element instead of ejb-ref element in the above tag for configuring the EJB's local interface. Check out the section Configuring Seam if local EJB references are used below to configure the Seam.


                  Configuring Websphere


                  Websphere has a feature called AutoLink to generate the JNDI names for the EJB3 coponent. With this, we will not be able to provide the JNDI names as configured in the components.xml. To override this feature, we need to add the below IBM specific deployment description in META-INF directory of the ejb jar file.


                  
                  META-INF/ibm-ejb-jar-bnd.xml
                  
                  <?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="SeamEJB"
                  
                                  simple-binding-name="ejb/Websphere_seam/xyz" />
                  
                  
                          <session name="EJB3">
                  
                                  <ejb-ref name="Websphere_seam/SeamEJB"
                  
                                          binding-name="ejb/Websphere_seam/xyz" />
                  
                          </session>
                  
                  
                  </ejb-jar-bnd>
                  
                  
                  



                  Configuring Seam if local EJB references are used


                  If a local EJB is configured, Seam will throw the following error


                  
                  Caused by: javax.naming.ConfigurationException: NamingManager.getURLContext cannot find the factory for this scheme: ejblocal
                  
                   at com.ibm.ws.naming.jndicos.CNContextImpl.checkForUrlContext(CNContextImpl.java:3389)
                  
                   at com.ibm.ws.naming.jndicos.CNContextImpl.lookupExt(CNContextImpl.java:1555)
                  
                   at com.ibm.ws.naming.util.IndirectJndiLookupObjectFactory$1.run(IndirectJndiLookupObjectFactory.java:374)
                  
                  
                  


                  Add the below configuration file to the root of the web context.


                  
                  file name seam-jndi.properties
                  
                  
                  
                  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
                  
                  
                  



                  Hope it helps. I am not sure, how I can upload my sample project.

                  • 6. Re: Seam Injecting EJB3 in Websphere.
                    Ken W Newbie

                    Hi all,


                    is there any update with this issue, I'm having the exact same problem as Praveen. I'm using SEAM 2.0.1 deployed on WebSphere 6.1.0.19 plus ejb3 fp. I've retraced all my configuration steps and perform clean re-install of everything and the same problem occured.  Did I miss something?



                    Java code:



                    @Local
                    public interface IClassB {
                         public boolean methodB(); 
                    }




                    @Stateless
                    @Name("iclassb")
                    public class ClassB implements IClassB {
                    
                         @Logger Log log;
                         
                         public boolean methodB() {
                              // TODO Auto-generated method stub
                              log.info("IN CLASS B");
                              return false;
                         }
                    
                    }





                    @Stateless
                    @Name("authenticator")
                    public class AuthenticatorAction implements Authenticator
                    {
                        @Logger Log log;
                        
                        @In Identity identity;
                        
                        @In(create = true) IClassB iclassb;
                       
                        ....



                    Web.xml


                    <ejb-local-ref>              
                        <ejb-ref-name>myproject/ClassB</ejb-ref-name>                
                        <ejb-ref-type>Session</ejb-ref-type>     
                        <local-home></local-home>
                        <local>com.mydomain.myproject.IClassB</local>  
                      </ejb-local-ref>



                    components.xml


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





                    This is the exception
                    org.jboss.seam.InstantiationException: Could not instantiate Seam component: iclassb
                    ....
                    Caused by: javax.naming.NameNotFoundException: Name comp/env/myproject not found in context java:.
                         at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.java:1767)

                    • 7. Re: Seam Injecting EJB3 in Websphere.
                      Jay Balunas Novice

                      @Sanjeev Sirigere - thanks for your explanation, and details into websphere's EJB 3 support.


                      @ Ken Sanjeev Sirigere's post added a lot of information regarding the details of WebSphere and it's support.  I would suggest reviewing his suggestions in addition to the reference guide chapter. 


                      The Seam team has not updated of the WebSphere chapter in some time, but it is next on the list for review.  When it is updated many of the suggestions provided by Sanjeev will be reviewed as well.


                      Please keep us informed of anything you find, and we will work it into the next update.


                      Regards,
                      Jay


                       

                      • 8. Re: Seam Injecting EJB3 in Websphere.
                        Ken W Newbie

                        Hi Jay,


                        I'll follow Sanjeev's suggestion.  Not really a WAS expert myself so will need to do some more reading/searching.  I'll post an update on my progress back here.  Looks like we'll have to manually bind the EJB - JNDI lookup and not use the  automatic reference target option.


                        Ken

                        • 9. Re: Seam Injecting EJB3 in Websphere.
                          John Eckhart Newbie

                          Sanjeev


                          In regards to the following:




                          Add the below configuration file to the root of the web context.


                          file name seam-jndi.properties
                          
                          
                          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
                          



                          I believe that these values are the defaults in WebSphere (http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.javadoc.doc/public_html/api/com/ibm/websphere/naming/PROPS.html), so pushing them to the initial context environment (which is what jndi.properties and seam-jndi.properties does) would seem to be redundant. Is this incorrect?

                          • 10. Re: Seam Injecting EJB3 in Websphere.
                            Sanjeev Sirigere Newbie

                            yes. you are right. It has been a long time I worked on this issue. As far as I remember, InitialContext was initial with some wrong values. Due to which the above behavior. Other alternative I tried that time after posting this response was just add an empty seam-jndi.properties. That would enable the InitialContext to have the right value.


                            Hope this helps