3 Replies Latest reply on Jun 22, 2012 4:27 AM by Matthias M.

    Lookup and invoke a _local_ EJB via a remote EJB by a remote client

    Matthias M. Newbie

      Hi there,

       

      I'm new to the jboss AS and the EJB. The book I've read doesn't help me, since the new JNDI naming changes so much.

       

      But during the last days I've managed to setup the server, deploy some remote stateful and stateless session beans. But now I'm trying something different:

      • Local stateless session bean named "TimeBean", with it's interface "ITimeLocal"
      • Remote stateless session bean named "CallerBean", with it's interface "ICallerRemote"
      • and a remote Client named "CallerClientBean"

       

      ITimeLocal

      package test.jboss.umweg.server.local;
      
      import javax.ejb.Local;
      
      @Local
      public interface ITimeLocal {
          public long getTime();
      }
      

       

      TimeBean

      package test.jboss.umweg.server.local;
      
      import java.util.Date;
      
      import javax.ejb.Local;
      import javax.ejb.Stateless;
      
      @Stateless
      @Local(ITimeLocal.class)
      public class TimeBean implements ITimeLocal {
      
          @Override
          public long getTime() {
              return new Date().getTime();
          }
      
      }
      

       

      So that's just the local bean. It was deployed successfully and the JNDI Bindings where created.

       

      The call from the CallerClientBean to the CallerBean works fine (I tested with "return 0").

       

      But when I tried the real call it wouldn't work:

      Extracted from CallerBean

      @Override
          public long askTime() {
              // lookup and invoke Local Bean, return time
              try {
                  Context context = getInitialContext();
                  ITimeLocal szb = (ITimeLocal) context.lookup(getJndiName());
                  long time = szb.getTime();
                  System.out.println("Time: " + time);
                  return time;
              } catch (NamingException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              return 0;
          }
      

       

      I build the InitialContext like this (though I didn't set a "jboss-ejb-client.properties" on server side, maybe that's a problem):

      private InitialContext getInitialContext() throws NamingException {
             Hashtable p = new Hashtable();
              p.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
              return new InitialContext(p);
          }
      

       

      And I tried two different JNDI names:

      • the same I've been building the other ones:
        ejb:/TimeBean//TimeBean!test.jboss.umweg.server.local.ITimeLocal
      • and the global JNDI binding I got from the deploy:
        java:global/TimeBean/TimeBean!test.jboss.umweg.server.local.ITimeLocal

       

      But I guess my main-problem is, that I'm not aware of howto call a local bean. And I couldn't find anything really helpful. I didn't post the Exceptions (first runtime, the illegalState), but I bet my faults are obvious to most people here

       

      Thanks!!

        • 1. Re: Lookup and invoke a _local_ EJB via a remote EJB by a remote client
          Matthias M. Newbie

          According to the Java EE Tutorial 6 (published 04/2012) there are three ways to create a local session bean:

          -------------------------------

          ■ Create an enterprise bean implementation class that does not implement a business

          interface, indicating that the bean exposes a no-interface view to clients. For example:

          @Session

          public class MyBean { ... }

          ■ Annotate the business interface of the enterprise bean as a @Local interface. For example:

          @Local

          public interface InterfaceName { ... }

          ■ Specify the interface by decorating the bean class with @Local and specify the interface

          name. For example:

          @Local(InterfaceName.class)

          public class BeanName implements InterfaceName { ... }

          -------------------------------

          If I try to add the "@Session" annotation to my class, eclipse doesn't recognize it and recommends to create such an annotation. (Wrong Setup? Just added the as7/bin/client/jboss-client.jar as a lib)


          So, there are only two ways left.

          -------------------------------

          ■ To obtain a reference to the no-interface view of an enterprise bean through dependency

          injection, use the javax.ejb.EJB annotation and specify the enterprise bean’s

          implementation class:

          @EJB

          ExampleBean exampleBean;

          ■ To obtain a reference to the no-interface view of an enterprise bean through JNDI lookup,

          use the javax.naming.InitialContext interface’s lookupmethod:

          ExampleBean exampleBean = (ExampleBean)

          InitialContext.lookup("java:module/ExampleBean");

          -------------------------------

          Dependency Injection fails because I cannot deploy these .jar files.

          Well and the JNDI lookup won't work either, regardless if I use "java:module/ExampleBean" or the longer option stated out by the server.

           

          Could PLEASE anyone help me? It has to be possible to call a local stateless session bean...

          • 2. Re: Lookup and invoke a _local_ EJB via a remote EJB by a remote client
            Wolf-Dieter Fink Master

            To call another Bean inside the container vie @Local you should not use InitialContext.

            Injection will do the work.

             

            {code}

            @Stateless

            public class My1Bean implements My1Remote {

                @EJB

                MyIntern intern;

             

              public void myMethod() {

                intern.hello();

              }

            }

             

            @Local

            public interface MyIntern {

                public void hello();

            }

             

            @Stateless

            public class MyInternBean implements MyIntern {

             

                @Override

                public void hello() {

                    // DO something

                }

             

            }

            {code}

             

            You might have a look to the JBoss quickstarts

            • 3. Re: Lookup and invoke a _local_ EJB via a remote EJB by a remote client
              Matthias M. Newbie

              Thank you that did it.

               

              Now I know why it wouldn't deploy:

              I seperated both server-sided beans into single jars. Consequently the jar containing the remote bean would fail, because of the implicit injection to the local bean, which wasn't reachable.

              But now both ways works:

              - Setting up an .ear file containing both beans

              - Exporting one .jar file containing both beans

               

              Thanks a lot!

               

              Furthermore I think I may have mixed up some different approaches to expose the beans.