9 Replies Latest reply on Jun 30, 2008 9:13 AM by j2ee4cxw

    JNDI EJB local lookup is ok, but the bean cannot be invoked

    j2ee4cxw

      We are building application based on Struts 2 and EJB 3. The server we use is JBOSS 4.2.2 GA. In the struts action class, we try to save data to database via ejb session bean. When the ejb was obtained via jndi romote look up, everything is fine. The bean is found and data is saved. However, when we do a local jndi lookup, the bean is found, but upon invoking the bean JBOSS threw following error:

      javax.ejb.EJBException: java.lang.IllegalArgumentException: Wrong target. class com.boeing.he.bessy.bean.ShipperManagerBean for public long com.boeing.he.bessy.bean.ShipperManagerBean.createShipper(com.boeing.he.bessy.domain.Shipper) throws com.boeing.he.bessy.exception.BessyException.

      This has happened to three of our developers with different beans. The bottom line is the local lookup is succeful, but the bean cannot be invoked. Any kind of suggestion is greatly appreciated. Thanks. Here are our codes:

      ////This is the save method of our Struts action class/////
      public String save()
      {
      try
      {

      //Shipper(spr) is our entity.
      com.boeing.he.bessy.domain.Shipper spr = new com.boeing.he.bessy.domain.Shipper();
      spr.setManifest("ABC");
      spr.setSite("PHL100");
      spr.setLocation("PHL");
      spr.setDocTypeCode("DOC100");


      //remote call. WORKS!
      // String SHIPPER_JNDI_NAME = "BessyEAR/ShipperManagerBean/remote";
      // Object ref1 = ServiceLocator.getEJB(SHIPPER_JNDI_NAME);//jndi lookup
      // ShipperManagerRemote smbean1 = (ShipperManagerRemote)ref1;
      // long shipperId1 = smbean1.createShipper(spr);
      // setMessage("Shipper Created with Id:" + shipperId1);

      //local call. Errors
      String SHIPPER_JNDI_NAME = "BessyEAR/ShipperManagerBean/local";
      Object ref2 = ServiceLocator.getEJB(SHIPPER_JNDI_NAME);//jndi lookup
      ShipperManagerLocal smbean2 = (ShipperManagerLocal) ref2;
      long shipperId2 = smbean2.createShipper(spr); ////<==ERROR OCURRED ON THIS LINE. ERROR OCURRED ON THIS LINE
      setMessage("Shipper Created with Id:" + shipperId2);

      }
      catch(Exception ex)
      {
      log.error(ex);
      setMessage("some error occurred");
      }

      return SUCCESS;
      }

      ///Interfaces////////
      public interface IShipperManager {

      public long createShipper(Shipper shipper) throws BessyException;
      }

      @Local
      public interface ShipperManagerLocal extends IShipperManager{}

      @Remote
      public interface ShipperManagerRemote extends IShipperManager {}

      ////The EJB session bean/////////
      @Stateless
      public class ShipperManagerBean implements ShipperManagerLocal,ShipperManagerRemote {
      @PersistenceContext(unitName="BessyPU")
      private EntityManager manager;

      public long createShipper(Shipper shipper) throws BessyException
      {
      manager.persist(shipper);
      return shipper.getShipperId();
      }
      }

      ////ServiceLocator///////
      public static Object getEJB(String jndiName) {
      Object object = null;
      try {
      InitialContext ctx = new InitialContext();
      object = ctx.lookup(jndiName);
      } catch (Exception e) {
      e.printStackTrace();
      }
      return object;
      }

        • 1. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
          jaikiran

          Please post the entire exception stacktrace.

          • 2. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
            j2ee4cxw

            The error stacktrace are the following, which really does not help much:

            09:17:20,080 INFO [STDOUT] [2008-06-27 09:17:20,080] DEBUG (MenuInterceptor.java:120) - MENU NAME = BessyMenu
            09:17:20,253 INFO [STDOUT] [2008-06-27 09:17:20,253] ERROR (LocalJndiCallAction.java:76) - javax.ejb.EJBException: java.lang.IllegalArgumentException: Wrong target. class com.boeing.he.bessy.bean.ShipperManagerBean for public long com.boeing.he.bessy.bean.ShipperManagerBean.createShipper(com.boeing.he.bessy.domain.Shipper) throws com.boeing.he.bessy.exception.BessyException
            09:17:20,285 INFO [STDOUT] [2008-06-27 09:17:20,285] INFO (LoggingInterceptor.java:67) - Starting execution stack for action //createShipperSave
            09:17:20,285 INFO [STDOUT] [2008-06-27 09:17:20,285] INFO (TimerInterceptor.java:187) - Executed action [//createShipperSave!save] took 236 ms.

            • 3. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
              itsme

              Do not cast for the bean just for the (remote) interface will do the trick.

              • 4. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
                j2ee4cxw

                Itsme: Thanks for your comment. I don't got what you mean. If I don't cast, how do you invoke the bean?

                • 5. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
                  itsme

                  Ah sorry, forgett about the last post.

                  Instead look for the ejb3 spec. There it is defined that an ejb cannot be both local and remote interface. Instead I would recommend, that you create a remote ejb as a facade that delegates it's work to the local interface

                  @Remote
                  public class ShipperManagerRemote extends IShipperManager {
                   Long createShipper(Shipper);
                  }
                  public class ShipperManagerRemoteBean implements ShipperManagerRemote {
                   @EJB private ShiperManagerLocal localShipperMgr;
                   public Long createShipper(Shipper s) {
                   return localShipperMgr.createShipper(s);
                   }
                  }
                  


                  • 6. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
                    jaikiran

                     

                    There it is defined that an ejb cannot be both local and remote interface


                    itsme, are we talking about the 4.6.6 section of the spec which says:

                    The same business interface cannot be both a local and a remote business interface of the bean.


                    In this example, j2ee4cxw is using two separate business interfaces. One for remote and one for local. That should not be a problem as far as i know. Feel free to correct me, if i am wrong :)

                    j2ee4cxw, I don't see anything obvious in your code, which might result in this exception.

                    ServiceLocator.getEJB(SHIPPER_JNDI_NAME);


                    Can you post the code in the getEJB method of ServiceLocator? And how frequently do you see this exception? Every time you use the local interface?

                    • 7. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
                      j2ee4cxw

                      jaikiran:

                      I made minor change to my deployment. The EJB jar used to be deployed to JBoss 4.2.2GA as jar file. Now it is deployed as exploded tree directory structure. I tested the whole process. Again, for jndi remote lookup, everything is fine, while for jnid local lookup it has run time error. How ever the error is slightly different:

                      10:13:40,932 INFO [STDOUT] [2008-06-27 10:13:40,932] ERROR (LocalJndiCallAction.java:76) - javax.ejb.EJBException: java.lang.RuntimeException: java.lang.ExceptionInInitializerError

                      ////Here is our jndi.properties file
                      java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
                      java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
                      java.naming.provider.url=localhost:8080/BessyWeb

                      /////Here is ServiceLocator.java
                      public class ServiceLocator {
                      private ServiceLocator() {
                      }
                      public static Object getEJB(String jndiName) {
                      Object object = null;
                      try {
                      InitialContext ctx = new InitialContext();
                      object = ctx.lookup(jndiName);
                      } catch (Exception e) {
                      e.printStackTrace();
                      }
                      return object;
                      }
                      }

                      • 8. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
                        jaikiran

                         

                        10:13:40,932 INFO [STDOUT] [2008-06-27 10:13:40,932] ERROR (LocalJndiCallAction.java:76) - javax.ejb.EJBException: java.lang.RuntimeException: java.lang.ExceptionInInitializerError


                        Is this the only thing that you see in the exception stacktrace? If yes, are you sure your application is not eating up the remaining part of the exception stacktrace? I would have expected a lot more details to be present in the stacktrace when this exception occurs. LocalJndiCallAction.java is probably your application's action class. Does it just print the exception "message" instead of printing out the entire stacktrace? Its really difficult to understand what the issue is without the entire exception stacktrace.

                        Btw,

                        java.naming.provider.url=localhost:8080/BessyWeb


                        This jndi url is incorrect. It should be:

                        java.naming.provider.url=localhost:1099


                        But i don't think this is causing the exception.


                        • 9. Re: JNDI EJB local lookup is ok, but the bean cannot be invo
                          j2ee4cxw

                          jaikiran:

                          The error stacktrace is the same as the one posted by somebody else here. The issue seems not from jndi lookup. The question is why remote lookup works and look lookup gives this error. Thanks a lot.

                          http://www.jboss.com/index.html?module=bb&op=viewtopic&t=127852