8 Replies Latest reply on Sep 29, 2014 6:21 AM by xavier flamant

    error when getting a remote EJB stateless session Bean (EJB)

    xavier flamant Newbie

      Hello,

       

      I work in java and use JBOSS eap 6.2

      I have an EJB  client and try to use a remote stateless EJB session that I get with a context (with an object Properties (see the code below).) In debug mode, when I do a lookup on my context to get my remote stateless EJB (in blue), it seems to work. But when I try to use a method of that remote bean (red line), I get the following error

       

       

      [CODE]

       

      EJBCLIENT000025: No EJB receiver available for handling [appName:EJBTutorial, moduleName:EJBTutorialEJB, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@56811df

      [/CODE]

       

      Have you an idea?

       

      [CODE]

      import java.io.BufferedReader;

      import java.io.IOException;

      import java.io.InputStreamReader;

      import java.util.List;

      import java.util.Properties;

       

      import javax.naming.Context;

      import javax.naming.InitialContext;

      import javax.naming.NamingException;

       

      import com.tutorialspoint.sessionbean.stateless.LibrarySessionBeanRemote;

       

      public class Main {

       

          BufferedReader brConsoleReader = null;

          Properties jndiProperties = new Properties();

          Context ctx = null;

          public void initializeContextAndConsoleReader() {

              // Context.URL_PKG_PREFIXES = "java.naming.factory.url.pkgs"

              jndiProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");

              // Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"

              jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");

              // Context.PROVIDER_URL = "java.naming.provider.url"

              jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");

              jndiProperties.put("jboss.naming.client.ejb.context", true);

              try {

                  ctx = new InitialContext(jndiProperties);

              } catch (NamingException ex) {

                  ex.printStackTrace();

              }

              brConsoleReader = new BufferedReader(new InputStreamReader(System.in));

          }

       

          public static void main(String[] args) {

              // TODO Auto-generated method stub

              Main ejbTester = new Main();

              ejbTester.initializeContextAndConsoleReader();

              ejbTester.testStatelessEjb();

          }

       

          public Context getContext() throws NamingException {

              return new InitialContext(jndiProperties);

          }

       

          /*

           * (non-Java-doc)

           *

           * @see java.lang.Object#Object()

           */

          public Main() {

              super();

          }

       

          private void showGUI() {

              System.out.println("**********************");

              System.out.println("Welcome to Book Store");

              System.out.println("**********************");

              System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");

          }

       

          private void testStatelessEjb() {

              try {

                  int choice = 1;

                  String viewClassName = LibrarySessionBeanRemote.class.getName();

                 LibrarySessionBeanRemote libraryBean = (LibrarySessionBeanRemote) ctx.lookup("ejb:EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"+ viewClassName);

                  while (choice != 2) {

                      String bookName;

                      showGUI();

                      String strChoice = brConsoleReader.readLine();

                      choice = Integer.parseInt(strChoice);

                      if (choice == 1) {

                          System.out.print("Enter book name: ");

                          bookName = brConsoleReader.readLine();

                          libraryBean.addBook(bookName);

                      } else if (choice == 2) {

                          break;

                      }

                  }

                  List<String> booksList = libraryBean.getBooks();

                  System.out.println("Book(s) entered so far: " + booksList.size());

                  for (int i = 0; i < booksList.size(); ++i) {

                      System.out.println((i + 1) + ". " + booksList.get(i));

                  }

       

                  LibrarySessionBeanRemote libraryBean1 = (LibrarySessionBeanRemote) ctx

                          .lookup("ejb:EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"

                                  + viewClassName);

                  List<String> booksList1 = libraryBean1.getBooks();

                  System.out.println("***Using second lookup to get library stateless object***");

                  System.out.println("Book(s) entered so far: " + booksList1.size());

                  for (int i = 0; i < booksList1.size(); ++i) {

                      System.out.println((i + 1) + ". " + booksList1.get(i));

                  }

              } catch (Exception e) {

                  System.out.println(e.getMessage());

                  e.printStackTrace();

              } finally {

                  try {

                      if (brConsoleReader != null) {

                          brConsoleReader.close();

                      }

                      ctx.close();

                  } catch (IOException | NamingException ex) {

                      System.out.println(ex.getMessage());

                  }

              }

       

          }

       

      }

      [/CODE]

        • 1. Re: error when getting a remote EJB stateless session Bean (EJB)
          Wolf-Dieter Fink Master

          You are mixing two different approaches.

          With a remote-naming InitialContext (you use remote://) the lookup must be EJBTutorial/EJBTutorialEJB/LibrarySessionBean!"+ viewClassName

          You use a lookup String which must be used if you use the ejb-client approach.

           

          It's recommended to use the ejb-client approach as the remote-naming has some drawbacks.

          • 2. Re: error when getting a remote EJB stateless session Bean (EJB)
            xavier flamant Newbie

            Hello Wolf and thank you for your answer. Now it works except some secondary details

             

            I used Both cases

             

            1) with a remote-naming context

             

            public void initializeStandardJNDIContext() {
               // Context.URL_PKG_PREFIXES = "java.naming.factory.url.pkgs"
               jndiProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");
               // Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
               jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
               // Context.PROVIDER_URL = "java.naming.provider.url"
               jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
               jndiProperties.put("jboss.naming.client.ejb.context", true);
               try {
               ctx = new InitialContext(jndiProperties);
               } catch (NamingException ex) {
               ex.printStackTrace();
               }

                }

             

            and I use the way you said : LibrarySessionBeanRemote libraryBean = (LibrarySessionBeanRemote) ctx.lookup("EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"+ viewClassName);

             

            But 2 other problems occured

             

            1-1) When I try to close my context (ctx.close()) I get the following error  (this doen't occur in the other way)

            ERROR: Close handler threw an exception

            java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@7b26b7df rejected from java.util.concurrent.ThreadPoolExecutor@2af1d0a3[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]

                at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)

             

            1-2) When I run several times as a Java Application from Eclipse it seems that it store the previouses results. Does it mean that when I run the application several times it uses the same session ?

             

             

            2) with the ejb-client approach

            public void initializeEJBCientAPIContext() {
               final Properties ejbProperties = new Properties();
               ejbProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
               ejbProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
               ejbProperties.put("remote.connections", "1");
               ejbProperties.put("remote.connection.1.host", "localhost");
               ejbProperties.put("remote.connection.1.port", "4447");
               //ejbProperties.put("remote.connection.1.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER"); // needed for forcing authentication over remoting (i.e. if you have a custom login module)
               //ejbProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false"); // needed for a login module that requires the password in plaintext
               ejbProperties.put("remote.connection.1.username", "flamant");
               ejbProperties.put("remote.connection.1.password", "_Antoine1");
               ejbProperties.put("org.jboss.ejb.client.scoped.context", "true"); // Not needed when EJBClientContext.setSelector is called programatically. ATTENTION: Client-Interceptor registration below does not work with this property! BUG?

             

               /*   final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(ejbProperties);
               final ConfigBasedEJBClientContextSelector selector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration);
               EJBClientContext.setSelector(selector);
               EJBClientContext.getCurrent().registerInterceptor(0, new TransactionInterceptor());*/

             

               try {
               ctx = new InitialContext(ejbProperties);
               } catch (NamingException ex) {
               ex.printStackTrace();
               }

                }

             

            And I use the following way LibrarySessionBeanRemote libraryBean = (LibrarySessionBeanRemote) ctx.lookup("ejb:EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"+ viewClassName);

            2-1) I have not the error when I close the context

            2-2) The results are stored when I run several times the program. Again does it mean that runing the program several times it keeps tha same session ?

            • 3. Re: error when getting a remote EJB stateless session Bean (EJB)
              xavier flamant Newbie

              Hello again,

               

              considering the fact that when I run the EJB client several time after from Eclipse it keep in memory the list of books I entered and considering I have a stateless remote bean, what would be the difference with a statefull EJB session bean ?

              • 4. Re: error when getting a remote EJB stateless session Bean (EJB)
                Wolf-Dieter Fink Master

                It depends on how your ejb look like. If you store something inside the SLSB you will break the contract. It's technical possible but you need to pick up the same SLSB instance or you have unexpected results.

                 

                1)

                I'm not sure maybe a problem in your code or a bug, could you try to reproduce with EAP6.3.1?

                2)

                If you use ScopedContext there is no possibility to use Interceptors at the moment, it is the expected behaviour.

                Whe you close the context for SC this will close the underlying connection. If you use the API with the selector the IC.close dosn't matter, the conneciton is keept as long the client is alive

                • 5. Re: error when getting a remote EJB stateless session Bean (EJB)
                  xavier flamant Newbie

                  Here is my stateless ejb

                   

                  interface

                  import java.util.List;

                   

                  import javax.ejb.Remote;

                   

                  @Remote

                  public interface LibrarySessionBeanRemote {

                   

                      void addBook(String bookname);

                   

                      List<String> getBooks();

                  }

                   

                  stateless bean

                  import java.util.ArrayList;

                  import java.util.List;

                   

                  import javax.ejb.Stateless;

                   

                  /**

                  * Session Bean implementation class LibrarySessionBean

                  */

                  @Stateless

                  public class LibrarySessionBean implements LibrarySessionBeanRemote {

                   

                      private List<String> bookShelf;

                   

                      /**

                       * Default constructor.

                       */

                      public LibrarySessionBean() {

                          // TODO Auto-generated constructor stub

                          bookShelf = new ArrayList<String>();

                      }

                   

                      public void addBook(String bookname) {

                          bookShelf.add(bookname);

                      }

                   

                      public List<String> getBooks() {

                          return bookShelf;

                      }

                   

                  }

                  • 6. Re: error when getting a remote EJB stateless session Bean (EJB)
                    xavier flamant Newbie

                    Hello Wolf-Dieter and thank you for your answer

                     

                    I think I found the answer for both problems answering in another forum.

                    1) it is the server job to close the context and only the server. So when I close the context, there is an error

                    2) there is probably a pool of one stateless session bean and that's why I get the list of books after opening a new connection.

                    • 7. Re: error when getting a remote EJB stateless session Bean (EJB)
                      Wolf-Dieter Fink Master

                      Yeah, with the private List you break the contract of "Stateless" as you have a state as you add the books to the list.

                      Now it depends extreme on the server implementation what happen.

                      It's strongly recommended to not use such approach!

                      • 8. Re: error when getting a remote EJB stateless session Bean (EJB)
                        xavier flamant Newbie

                        Thank-you again for your answer Wolf-Dieter,

                         

                        it is clear and solved now