9 Replies Latest reply on Nov 6, 2013 4:45 PM by wdfink

    Problem appreciating the stateless bean behavior

    oceanvijai

      Hi,

          I am a newbie to EJB and started off with EJB 3.0. It annotations are cool but when I was trying to study EJB stateless session bean behavior by trying some samples, I got stuck up. The details are as follows,

       

      I created a stateless session bean as follows,

       

      stateless remote interface.

       

      package sample.testing.EJBs.sessionBean.stateless;
      
      
      import javax.ejb.Remote;
      
      
      @Remote
      public interface FirstStatelessSessionBeanRemote 
      {
        public String getMyName();
      
        public void appendName( String nameToAppend);
      }
      
      
      
      
      
      

       

       

       

      stateless bean impl

      package sample.testing.EJBs.sessionBean.stateless;
      import javax.ejb.Remote;
      import javax.ejb.Stateless;
      /**
       * Session Bean implementation class FirstStatelessSessionBean
       */
      @Stateless (name="vijai'sFirstStatelessSessionBean")
      public class FirstStatelessSessionBean implements FirstStatelessSessionBeanRemote {
          /**
           * Default constructor. 
           * 
           */
          public FirstStatelessSessionBean() {
              name = "vijai";
          }
          private String name="";
        @Override
        public String getMyName() {
        // TODO Auto-generated method stub
        return getName();
        }
        @Override 
        public void appendName(String nameToAppend) {
        name += nameToAppend;
        }
        public String getName() {
        return name;
        }
        public void setName(String name) {
        this.name = name;
        }
      }
      

       

      So I deployed this as a jar is the same Jboss 7.1 server. For testing I created a simple servlet application and tested as follows,

       

      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
        final Hashtable jndiProperties = new Hashtable();
               jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
               final Context context = new InitialContext(jndiProperties);
               response.getWriter().println(context.getEnvironment());
               
               
        String app_name="";
        String module_name="/sampleEJBProject";
        String distinct_name="/";
        String bean_name="/vijai'sFirstStatelessSessionBean";
        String remoteInterface_name="sample.testing.EJBs.sessionBean.stateless.FirstStatelessSessionBeanRemote";
      
      
        String ejbBeanJNDIName = "ejb:"+app_name+module_name+distinct_name+bean_name+"!"+remoteInterface_name;
        response.getWriter().println(ejbBeanJNDIName);
        Object obj = context.lookup(ejbBeanJNDIName);
      
      
      
        response.getWriter().println(obj);
        FirstStatelessSessionBeanRemote bean = (FirstStatelessSessionBeanRemote)obj;
        bean.appendName("Vijai");
        response.getWriter().println(bean.getMyName());
      
        bean.appendName("anand");
        response.getWriter().println(bean.getMyName());
      
      
        } catch (Exception e) {
        e.printStackTrace();
        response.getWriter().println(e.getMessage());
        }
      
      
      
      
      

       

      The result was something like this,

      1st refresh: vijaVijaianand

      2nd refresh: vijaVijaianandVijaianand

      3rd refresh: vijaVijaianandVijaianandVijaianand

      and so.... but as per the definition of a stateless bean, the scope is expected to be destroyed after the invocation method is complete right ?

      so I should be getting something like

       

      1st refresh: vijaVijaianand

      2nd refresh: vijaVijaianand

      3rd refresh: vijaVijaianand

       

      But I dont, can anyone advice me when am I doing wrong here please....

        • 1. Re: Problem appreciating the stateless bean behavior
          dibyendudev

          I have also faced the same kind of issue though I have used the local interface where you have used the remote one, I think this is because of the fact that the you are calling the business method one after another which does not let the stateless bean to get destroyed or going out of scope. Please post if you find any useful answer.


          vijai vasudevan as you are successful to use the Remote interface I have query to you.


          I am getting a "No EJB receiver to handle" Exception while calling the business method. Can you please help me in sorting out that.

          I am giving the entire code and configuration below.



          Hi All,

          I am very new to EJB3 and jboss.

          Below is the environment I am using.

           

           

          eclipse juno.

          jboss 7.1

          EJB 3.0

           

           

          Description :

           

           

          I have made an EJB project in which I have a simple stateless bean. I have another class in the same application which is acting as the client and trying to access the Bean remotely.

           

           

          Below are the codes:

           

           

          package com.ibytecode.businesslogic;

           

          Bean class:

           

           

          import com.ibytecode.business.HelloWorld;

          import javax.ejb.Stateless;

           

          @Stateless

          public class HelloWorldBean implements HelloWorld {

              public HelloWorldBean() {

              }

           

              public String sayHello() {

                  return "Hello World !!!";

              }

          }

           

           

          Business Interface :

           

           

          package com.ibytecode.business;

          import javax.ejb.Remote;

           

          @Remote

          public interface HelloWorld {

              public String sayHello();

          }

           

           

          EJB client code :

           

           

          package com.ibytecode.client;

           

          import javax.naming.Context;

          import javax.naming.NamingException;

           

          import com.ibytecode.business.HelloWorld;

          import com.ibytecode.businesslogic.HelloWorldBean;

          import com.ibytecode.clientutility.ClientUtility;

           

          public class EJBApplicationClient {

           

              public static void main(String[] args) {

                  HelloWorld bean = doLookup();

                  System.out.println(bean.sayHello()); // 4. Call business logic

              }

           

              private static HelloWorld doLookup() {

                  Context context = null;

                  HelloWorld bean = null;

                  try {

                      // 1. Obtaining Context

                      context = ClientUtility.getInitialContext();

                      // 2. Generate JNDI Lookup name

                      String lookupName = getLookupName();

                      // 3. Lookup and cast

                      bean = (HelloWorld) context.lookup(lookupName);

           

                  } catch (NamingException e) {

                      e.printStackTrace();

                  }

                  return bean;

              }

           

              private static String getLookupName() {

          /*

          The app name is the EAR name of the deployed EJB without .ear suffix.

          Since we haven't deployed the application as a .ear,

          the app name for us will be an empty string

          */

                  String appName = "";

           

                  /* The module name is the JAR name of the deployed EJB

                  without the .jar suffix.

                  */

                  String moduleName = "HelloWorldSessionBean";

           

          /*AS7 allows each deployment to have an (optional) distinct name.

          This can be an empty string if distinct name is not specified.

          */

                  String distinctName = "";

           

                  // The EJB bean implementation class name

                  String beanName = HelloWorldBean.class.getSimpleName();

           

                  // Fully qualified remote interface name

                  final String interfaceName = HelloWorld.class.getName();

           

                  // Create a look up string name

                  String name = "ejb:" + appName + "/" + moduleName + "/" +

                      distinctName    + "/" + beanName + "!" + interfaceName;

           

                  return name;

              }

          }

           

           

          EJB client utility(I have created for convenience) :

           

           

          package com.ibytecode.clientutility;

           

          import java.util.Properties;

          import javax.naming.Context;

          import javax.naming.InitialContext;

          import javax.naming.NamingException;

           

          public class ClientUtility {

           

              private static Context initialContext;

           

              private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming";

           

              public static Context getInitialContext() throws NamingException {

                  if (initialContext == null) {

                      Properties properties = new Properties();

                      properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES);

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

                      initialContext = new InitialContext(properties);

                  }

                  return initialContext;

              }

           

          }

           

           

           

           

          jboss-ejb-client.properties:

           

           

          endpoint.name=client-endpoint

          remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false

          remote.connections=default

          remote.connection.default.host=localhost

          remote.connection.default.port = 4447

          remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

           

           

           

           

          Exception stack:

           

           

          Nov 03, 2013 4:47:40 AM org.jboss.ejb.client.EJBClient <clinit>

          INFO: JBoss EJB Client version 1.0.5.Final

          Exception in thread "main" java.lang.IllegalStateException: No EJB receiver available for handling [appName:,modulename:HelloWorldSessionBean,distinctname:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@786bb78a

            at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584)

            at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119)

            at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181)

            at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136)

            at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121)

            at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104)

            at $Proxy0.sayHello(Unknown Source)

            at com.ibytecode.client.EJBApplicationClient.main(EJBApplicationClient.java:14)

           

           

          JAR Added:

           

          I have added jboss-client.jar from <jboss home>\bin folder.

           

           

          Please suggest what is missing or wrong.


          • 2. Re: Problem appreciating the stateless bean behavior
            wdfink

            Could you show the relevant part of logfile where the JNDI names are shown?

            • 3. Re: Problem appreciating the stateless bean behavior
              dibyendudev

              Below is the log when starting the jboss from eclipse.

               

              06:21:26,704 INFO  [org.jboss.modules] JBoss Modules version 1.1.1.GA

              06:21:26,938 INFO  [org.jboss.msc] JBoss MSC version 1.0.2.GA

              06:21:27,001 INFO  [org.jboss.as] JBAS015899: JBoss AS 7.1.1.Final "Brontes" starting

              06:21:27,924 INFO  [org.xnio] XNIO Version 3.0.3.GA

              06:21:27,925 INFO  [org.jboss.as.server] JBAS015888: Creating http management service using socket-binding (management-http)

              06:21:27,935 INFO  [org.xnio.nio] XNIO NIO Implementation Version 3.0.3.GA

              06:21:27,946 INFO  [org.jboss.remoting] JBoss Remoting version 3.2.3.GA

              06:21:27,979 INFO  [org.jboss.as.logging] JBAS011502: Removing bootstrap log handlers

              06:21:27,983 INFO  [org.jboss.as.configadmin] (ServerService Thread Pool -- 26) JBAS016200: Activating ConfigAdmin Subsystem

              06:21:28,014 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 31) JBAS010280: Activating Infinispan subsystem.

              06:21:28,045 INFO  [org.jboss.as.connector.subsystems.datasources] (ServerService Thread Pool -- 27) JBAS010403: Deploying JDBC-compliant driver class org.h2.Driver (version 1.3)

              06:21:28,057 INFO  [org.jboss.as.connector] (MSC service thread 1-7) JBAS010408: Starting JCA Subsystem (JBoss IronJacamar 1.0.9.Final)

              06:21:28,090 INFO  [org.jboss.as.osgi] (ServerService Thread Pool -- 39) JBAS011940: Activating OSGi Subsystem

              06:21:28,107 INFO  [org.jboss.as.naming] (ServerService Thread Pool -- 38) JBAS011800: Activating Naming Subsystem

              06:21:28,134 INFO  [org.jboss.as.security] (ServerService Thread Pool -- 44) JBAS013101: Activating Security Subsystem

              06:21:28,149 INFO  [org.jboss.as.security] (MSC service thread 1-1) JBAS013100: Current PicketBox version=4.0.7.Final

              06:21:28,173 INFO  [org.jboss.as.naming] (MSC service thread 1-7) JBAS011802: Starting Naming Service

              06:21:28,180 INFO  [org.jboss.as.mail.extension] (MSC service thread 1-7) JBAS015400: Bound mail session [java:jboss/mail/Default]

              06:21:28,186 INFO  [org.jboss.as.webservices] (ServerService Thread Pool -- 48) JBAS015537: Activating WebServices Extension

              06:21:28,372 INFO  [org.jboss.ws.common.management.AbstractServerConfig] (MSC service thread 1-2) JBoss Web Services - Stack CXF Server 4.0.2.GA

              06:21:28,816 INFO  [org.jboss.as.server.deployment.scanner] (MSC service thread 1-5) JBAS015012: Started FileSystemDeploymentService for directory D:\WebsiteA\jboss-as-7.1.1.Final\jboss-as-7.1.1.Final\standalone\deployments

              06:21:28,829 INFO  [org.jboss.as.remoting] (MSC service thread 1-6) JBAS017100: Listening on localhost/127.0.0.1:4447

              06:21:28,836 INFO  [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) JBAS015003: Found HelloWorldSessionBean.jar in deployment directory. To trigger deployment create a file called HelloWorldSessionBean.jar.dodeploy

              06:21:28,858 INFO  [org.apache.coyote.http11.Http11Protocol] (MSC service thread 1-5) Starting Coyote HTTP/1.1 on http-localhost-127.0.0.1-8080

              06:21:28,895 INFO  [org.jboss.as.remoting] (MSC service thread 1-5) JBAS017100: Listening on /127.0.0.1:9999

              06:21:28,985 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-5) JBAS010400: Bound data source [java:jboss/datasources/ExampleDS]

              06:21:29,017 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015876: Starting deployment of "HelloWorldSessionBean.jar"

              06:21:29,136 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-3) JNDI bindings for session bean named HelloWorldBean in deployment unit deployment "HelloWorldSessionBean.jar" are as follows:

               

               

                java:global/HelloWorldSessionBean/HelloWorldBean!com.ibytecode.business.HelloWorld

                java:app/HelloWorldSessionBean/HelloWorldBean!com.ibytecode.business.HelloWorld

                java:module/HelloWorldBean!com.ibytecode.business.HelloWorld

                java:jboss/exported/HelloWorldSessionBean/HelloWorldBean!com.ibytecode.business.HelloWorld

                java:global/HelloWorldSessionBean/HelloWorldBean

                java:app/HelloWorldSessionBean/HelloWorldBean

                java:module/HelloWorldBean

               

               

              06:21:29,254 INFO  [org.jboss.as] (MSC service thread 1-7) JBAS015951: Admin console listening on http://127.0.0.1:9990

               

               

               

              06:21:29,254 INFO  [org.jboss.as] (MSC service thread 1-7) JBAS015874: JBoss AS 7.1.1.Final "Brontes" started in 2842ms - Started 172 of 249 services (76 services are passive or on-demand)

              06:21:29,433 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "HelloWorldSessionBean.jar"

               

               

              My JNDI look up String is :

               

              Look up string ::: ejb:/HelloWorldSessionBean//HelloWorldBean!com.ibytecode.business.HelloWorld

               

              I have deployed the bean as a jar thus the application name is blank and the jar name is HelloWorldSessionBean Business interface name is HelloWorld .

               

              I dont think that there is any problem with the JNDI lookup because the proxy is being returned successfully, the Exception occurs when I am trying to call the business method that is

              bean.sayHello()  in the above code.

               

              Please help

              • 4. Re: Problem appreciating the stateless bean behavior
                oceanvijai
                Hi Dibyendu,

                     I may not have a exact answers for both your's and mine, but I can help a bit to narrow it down from my continues effort so far and I also would like it someone finish this off.


                Q1. This is my question regarding the stateless behavior of the bean I created.

                        From my learning further I learnt that the stateless bean I got on my every invocation is a pooled stateless session bean whose life cycle is not complete yet. This was the clue I got from the oracle doc. To he exact " Clients may, however, change the state of instance variables in pooled stateless beans, and this state is held over to the next invocation of the pooled stateless bean." (http://docs.oracle.com/javaee/5/tutorial/doc/bnbly.html). So we should not expect the same instance every time we do a lookup for a stateless bean.

                     It does made sense to me, but I did not get the stateless session bean to work exactly the way I expected. Because one way to test it is to make some configurations in the JBoss 7.1 console, where we can set the pool configs and stateless EJB instance timeouts and time to live value. I am not able to successively make the EJB container to destroy the EJB instances after every invocations.


                If someone is able is to show me a proper doc to study and test the pool configurations would be very helpful.   


                O2.  With regards to "No EJB receiver to handle"...

                          Yes, I too had this problem, but I did no change in my code to fix this. Just try to redeploy it many times and it worked. I know this is not the proper answer, but still it worked for me for now until we find the exact answer.

                            Also I was able to successfully fix this only in the standalone JBoss 7.1 server, where as in the Liferay Jboss bundle server I still am not able to fix this. Hope I someone helps us / I find the issues.



                Regards,

                Vijai


                • 5. Re: Problem appreciating the stateless bean behavior
                  wdfink

                  The problem might be the JNDI or the server connection.

                  With AS7 the creation of the proxy is client local action, therefore you get the first error if you invoke the remote method.

                  Maybe there is a problem with the credentials as the connection is secured by default (except local connections).

                  You might add an application user (use bin/add-user.*) and set the username and password in the jboss-ejb-client.properties.

                   

                  You might have a look to the documentation or this quickstart

                  • 6. Re: Problem appreciating the stateless bean behavior
                    dibyendudev

                    wfink, thanx for your reply. I have tried doing that as well it did no work. Even I disable the security and tried then also it did not work. Can you suggest something??

                    • 7. Re: Problem appreciating the stateless bean behavior
                      wdfink

                      Did the quickstart is not working for you?

                       

                      You might activate the "org.jboss" TRACE level at client side, it might give you a hint what's wrong

                      • 8. Re: Problem appreciating the stateless bean behavior
                        dibyendudev

                        That is what I want to do now, can you please tell me how to activate the TRACE level in client side.

                        • 9. Re: Problem appreciating the stateless bean behavior
                          wdfink

                          You can use the programatic approach, use java.util.logging.Logger and set the level for "org.jboss" logger to level FINEST.

                          Other option is to use a log4j.properties and activate it by jvm options, see log4j page