Discussions

EJB programming & troubleshooting: Problem with looking up local interfaces in WebSphere 5.1

  1. Problem with looking up local interfaces in WebSphere 5.1 (15 messages)

    I am very new to WebSphere and I have ported my JBoss application to WebSphere 5.1. Currently I only have one Stateless Session EJB deployed.

    I have registerd the JNDI name of the remote bean as: ejb/ProductFactory with WebSphere.

    First, the JNDI naming service finds the remote home interface just fine when I do:
    Object objref = context.lookup("ejb/ProductFactory");
    ProductFactoryHome home = (ProductFactoryHome) PortableRemoteObject.narrow(objref, ProductFactoryHome.class);
    factory = (ProductFactory) home.create();

    ...but, I get an error:
    java.lang.ClassCastException: cannot cast class com.ibm.ejs.container._EJSWrapper_Stub to interface com.forisent.framework.productManager.store.ProductFactoryHome.

    ProductFactoryHome being my remote home interface.

    I am using WebSphere studio and I am forced to generate RMIC code before anything will deploy. This creates a bunch of duplicate classes in my path with my session bean's name and a bunch of tacked on number. (confused)

    Then, when I try to access the local home interface:
    ProductFactoryLocalHome home = (ProductFactoryLocalHome) context.lookup("ejb/ProductFactoryLocalHome");
    factory = (ProductFactoryLocal) home.create();

    ... and keep getting JNDI name not found exceptions:
    javax.naming.NameNotFoundException: ejb/ProductFactoryLocalHome. Root exception is org.omg.CosNaming.NamingContextPackage.NotFound

    I have tried all sorts of lookup paths:
    java:comp/env/ejb/ProductFactoryLocalHome
    ProductFactoryLocal
    ejb/ProductFactoryLocalHome
    etc
    etc
    etc

    and none seem to work. All this was super easy with JBoss and just stopped working in WebSphere.

    Threaded Messages (15)

  2. Is there any furhter information I can supply that would help someone here think of what might be wrong?
  3. Ejb-jar.xml file[ Go to top ]

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
    <ejb-jar id="ejb-jar_ID">
    <display-name>ProductManager</display-name>

    <enterprise-beans>

          <!-- Session Beans -->
          <session id="Session_1072496206033">
             <description><![CDATA[]]></description>
             <display-name>ProductFactory</display-name>

             <ejb-name>ProductFactory</ejb-name>

             <home>com.forisent.framework.productManager.store.ProductFactoryHome</home>
             <remote>com.forisent.framework.productManager.store.ProductFactory</remote>
             <local-home>com.forisent.framework.productManager.store.ProductFactoryLocalHome</local-home>
             <local>com.forisent.framework.productManager.store.ProductFactoryLocal</local>
             <ejb-class>com.forisent.framework.productManager.store.ProductFactoryBean</ejb-class>
             <session-type>Stateless</session-type>
             <transaction-type>Container</transaction-type>
          </session>
          

         </enterprise-beans>
    </ejb-jar>
  4. And here is the ibm-ejb-jar-bnd.xml file[ Go to top ]

    <?xml version="1.0" encoding="UTF-8"?>
    <ejbbnd:EJBJarBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ejbbnd="ejbbnd.xmi" xmlns:ejb="ejb.xmi" xmi:id="EJBJarBinding_1072503836054">
      <ejbJar href="META-INF/ejb-jar.xml#ejb-jar_ID"/>
      <ejbBindings xmi:id="EnterpriseBeanBinding_1072503836054" jndiName="ejb/ProductFactory">
        <enterpriseBean xmi:type="ejb:Session" href="META-INF/ejb-jar.xml#Session_1072496206033"/>
      </ejbBindings>
    </ejbbnd:EJBJarBinding>
  5. ok, sort of figured it out[ Go to top ]

    Ok, so I did some print out statements of my context path and discovered that even though I specify the local bean JNDI name as ProductFactoryLocal, it is still being registered as ProductFactory but under the “local:ejb” context. So, I can now access my local bean via “local:ejb/ProductFactory”.

    However, if I move my EAR to a different container, will the path “local:ejb” work? In other words, is this a J2EE spec compliant path declaration or is this a WebSphere only thing?
  6. Create EJB reference[ Go to top ]

    Create an EJB reference for your EJB in the web deployment descriptor and lookup using java:comp/env.
  7. local ejbs[ Go to top ]

    You shouldn't look up local EJBs using global JNDIs. Define a local reference in the component that is doing the lookup, i.e. the calling EJB or the Web module. Bind the reference to the same JNDI name as the EJB. Then, look up using java:comp/env followed by the reference name.
  8. hi, I am facing the same problem. Would you kindly share what was the work around that you implementated to solve the error?

    thanks
  9. I am actually working with WebSphere 6.0. My bean was registered under jndi-name="ejb/myBeans/MyGreatBean".

    I had to do the lookup to local interface through ctx.lookup("local:ejb/ejb/myBeans/MyGreatBean");
    And I can lookup remote interface through:
    ctx.lookup("ejb/myBeans/MyGreatBean");

    I do not know why there must be additional "ejb/" prefix, while my jndi name already starts with "ejb/", but it works.
  10. local session bean[ Go to top ]

    Context cmp = (Context) new InitialContext();
    PaymentDAOLocalHome home = (PaymentDAOLocalHome) cmp.lookup("local:ejb/ejb/PaymentDAO");
    factory = (PaymentDAOLocal) home.create();

    my jndi binding name is ejb/PaymentDAO.
    You have tollok up local session bean as local:ejb/ejb/PaymentDAO.

    i wonder why i have to append extra ejb as jndi binding name it self has ejb/PaymentDAO.
    Any way it works when u look up as mentioned in above code.
    Just to update...
  11. The local: context is a hidden part of the internal implementation of WAS and should never ever be used by customer code. It may change or stop working at any time, with no warning, if WAS decides to modify its internal implementation (which is likely to happen sometime). The only supported mechanism in WAS for looking up local EJB homes is to define an ejb-local-ref in the calling component and then do the lookup in java:comp/env.
  12. It doesn't work[ Go to top ]

    Hi Randy,
    The local: context is a hidden part of the internal implementation of WAS and should never ever be used by customer code. It may change or stop working at any time, with no warning, if WAS decides to modify its internal implementation (which is likely to happen sometime). The only supported mechanism in WAS for looking up local EJB homes is to define an ejb-local-ref in the calling component and then do the lookup in java:comp/env.
    Thanks for the info but in your way it doesn't work, here is my descriptor: ServiceEJB com.bmc.appl.ServiceHome com.bmc.appl.Service com.bmc.appl.ejb.ServiceBean Stateless Container local/com.bmc.appl.LocalServiceHome Session com.bmc.appl.LocalServiceHome com.bmc.appl.LocalService LocalServiceEJB com.bmc.appl.LocalServiceHome com.bmc.appl.LocalService com.bmc.appl.LocalServiceBean Stateless Container lookup on the remote EJB is success but when the remote wants to lookup the local it fails :( Do I need to lookup with the full InitialContext when looking for local EJBs or just empty: new InitialContext();?? Oded
  13. Re: It doesn't work[ Go to top ]

    Your descriptor is missing the declaration of the target for your ejb-local-ref to point to. (That should either be specified in the ejb-link stanza within your DD, or manually resolved to the target during app assembly (using AST or RAD) or during app installation (using WAS system management.) This is not specific to WebSphere; the J2EE specs outline how this works. To resolve the ejb-local-ref within your DD, you would change your ejb-link stanza to be: LocalServiceEJB Randy
  14. Re: It doesn't work[ Go to top ]

    Also...within your ServiceEJB code, the JNDI lookup for the LocalServiceHome would be done as follows: InitialContext ic = new InitialContext(); object obj = ic.lookup("java:comp/env/local/com.bmc.appl.LocalServiceHome");
  15. It works, but...[ Go to top ]

    Hi Randy, Thanks for the answer, helped a lot. Now I have a new issue, if I am looking for a local EJB directly from another one (remote one) it works, but if the first EJB lookup for the local EJB via helper class the chain breaks and it doesn't work again. ServiceEJB class calls Utils.getLocalServiceEJB fails. Am I missing something? Thanks again, Oded
  16. I am using Websphere 5.1. I had a session bean having local view only and having jndi name "ejb/com/ibm/idaf/exception/EventMgmtLocalHome" in deployment descriptor. I was accessing this bean from a servlet using jndi lookup name "local:ejb/com/ibm/idaf/exception/EventMgmtLocalHome" but it didn't run but when I used "local:ejb/ejb/com/ibm/idaf/exception/EventMgmtLocalHome" it run. I don't know why extra ejb/ is required.
    I created ejb local ref in servlet's web.xml also. It runs fine. This is the right way to lookup local interface of ejb.
    I am agreed on following statement posted by Randy. This is written in websphere docs as well.
    The local: context is a hidden part of the internal implementation of WAS and should never ever be used by customer code. It may change or stop working at any time, with no warning, if WAS decides to modify its internal implementation (which is likely to happen sometime). The only supported mechanism in WAS for looking up local EJB homes is to define an ejb-local-ref in the calling component and then do the lookup in java:comp/env.