11 Replies Latest reply: Oct 25, 2010 6:00 PM by Jamie Blake RSS

    Session bean Asynchronous Invocation

    mojito java Newbie

      hello,

      I'am testing the new feature of the EJB 3.1 concerning the asynchronous invocation using JBOSSAS 6.0.0M4

      Strangely, i'm not having an asynchronous behaviour, my client is blocked when calling the asynchronous method

      i am using two EJB3.1 session beans :

       

      My asynchronous method

      @Asynchronous
      public void changeState() {
      System.out.println("change state started");
      number++;
      try {
      Thread.sleep(10000);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      setState("asychronous call succeded");
      System.out.println("change state finished");
      //System.err.println("asychronous call succeded");
      //return new AsyncResult<String>(getState());
      }

      @Asynchronous

      public void changeState() {

      System.out.println("change state started");

      number++;

      try {

      Thread.sleep(10000);

      } catch (InterruptedException e) {

      e.printStackTrace();

      }

      System.out.println("change state finished");

      }

       

      My Client call :

       

      public String sayHello(){

          String test = null;

          System.out.println("Accesing the async invocation");

          masr.changeState();// this is the call to the asynchronous method

      System.out.println("i will get the result later");

      System.out.println("after doing somthing else");

      return "i finally got the answer";   

          }

       

      i tried the same thing using Future<V> and i'm having the same resultes.i'm wondering if thread.sleep() method is not suitable for an asynchronous call or if the trace using sysout is not convenient for having a trace of an asynchronous call.

       

      Thank u for ur help

        • 1. Re: Session bean Asynchronous Invocation
          mojito java Newbie

          i ve deployed the beans on Glassfish v3 and i got an asynchronous behaviour.

          Am i missing any configuration under JBoss?

          • 2. Re: Session bean Asynchronous Invocation
            jaikiran pai Master

            mojito java wrote:

             


                masr.changeState();// this is the call to the asynchronous method

            What is "masr" and how do you get hold of that instance? Can you post that relevant code and also the appropriate bean class?

            • 3. Re: Session bean Asynchronous Invocation
              mojito java Newbie

              package beans;
              import java.util.concurrent.Future;
              import javax.ejb.AsyncResult;
              import javax.ejb.Asynchronous;
              import javax.ejb.Singleton;
              import org.apache.cxf.endpoint.Server;
              /**
              * Session Bean implementation class MyAsyncStateless
              */
              @Singleton
              public class MyAsyncStateless implements MyAsyncStatelessRemote {
              private int number;
              public int getNumber() {
              return number;
              }
              public void setNumber(int number) {
              this.number = number;
              }
              public String getState() {
              return state;
              }
              public void setState(String state) {
              this.state = state;
              }
              String state;
              public MyAsyncStateless() {
              }
              @Asynchronous
              public Future<String> changeState() {
              System.out.println("change state started");
              try {
              Thread.sleep(60000);
              } catch (InterruptedException e) {
              e.printStackTrace();
              }
              setState("asychronous call succeded");
              System.out.println("change state finished");
              return new AsyncResult<String>(getState());
              }
              public String tellState() {
              return getState() + "    " + getNumber();
              }
              }

              package beans;

               

              import java.util.concurrent.Future;

              import javax.ejb.AsyncResult;

              import javax.ejb.Asynchronous;

              import javax.ejb.Singleton;

              import org.apache.cxf.endpoint.Server;

               

              /**

              * Session Bean implementation class MyAsyncStateless

              */

              @Singleton

              public class MyAsyncStateless implements MyAsyncStatelessRemote {

               

              private int number;

               

              public int getNumber() {

              return number;

              }

               

              public void setNumber(int number) {

              this.number = number;

              }

               

              public String getState() {

              return state;

              }

               

              public void setState(String state) {

              this.state = state;

              }

               

              String state;

               

              public MyAsyncStateless() {

              }

               

              @Asynchronous

              public Future<String> changeState() {

              System.out.println("change state started");

              try {

              Thread.sleep(60000);

              } catch (InterruptedException e) {

              e.printStackTrace();

              }

              setState("asychronous call succeded");

              System.out.println("change state finished");

              return new AsyncResult<String>(getState());

              }

               

              public String tellState() {

              return getState() + "    " + getNumber();

              }

               

              }

              Client Bean :
              package beans;
              import java.util.concurrent.ExecutionException;
              import java.util.concurrent.Future;
              import javax.ejb.EJB;
              import javax.ejb.EJBException;
              import javax.ejb.Stateless;
              @Stateless
              public class MyAsyncTest implements MyAsyncTestRemote {
              @EJB
              MyAsyncStatelessRemote masr;
              public MyAsyncTest() {
              }
              public String sayHello() {
              String test = null;
              System.out.println("Accesing the async invocation");
              Future<String> myFutureResult = null;
              try {
              myFutureResult = masr.changeState();
              System.out.println(myFutureResult.isCancelled());
              } catch (EJBException ejbex) {
              }
              System.out.println("i will get the result later");
              System.out.println("after doing somthing else");
              try {
              test = myFutureResult.get();
              } catch (InterruptedException e) {
              e.printStackTrace();
              } catch (ExecutionException e) {
              e.printStackTrace();
              }
              System.out.println("i finally got the answer");
              return "i finally got the answer";
              }
              }

              • 4. Re: Session bean Asynchronous Invocation
                mojito java Newbie

                i'm sorry for the mess i made here.

                I changed my MyAsyncStateless type, when i made it stateless (and stateful later)  that worked fine...but still the same problem with a singleton bean (i checked in jboss and i do not have any other singleton instance)

                • 5. Re: Session bean Asynchronous Invocation
                  Jamie Blake Newbie

                  Does anyone have an update as to when/if @Asynchronous will be implemented in JBOSS 6, for EJB 3.1?

                   

                  I am wanting this feature and am currently finding it not work as mentioned here, this is in M5.

                   

                  Thanks!

                  • 6. Re: Session bean Asynchronous Invocation
                    jaikiran pai Master

                    @Asynchronous invocation (except on nointerface view) is available in AS 6.0.0.M4/M5. The nointerface view @Asynchronous invocation bug will be fixed before AS 6.0 goes GA. What exact issue are you running into? Please post the relevant details including the code and any configs and logs.

                    • 7. Re: Session bean Asynchronous Invocation
                      Jamie Blake Newbie

                      Hi Jaikiran pai,

                       

                      I have an MDB that listens to a queue to do some work.

                       

                      The on message calls and EJB method, that calls another EJB method that is annotated with the @Asynchronous, see excerpt below

                       

                      The MDB calls this:

                      executeService(params);

                       

                      Here is the first bean that is called from MDB...

                       

                      @Stateless(name = "AdmStageBean")

                      public class AdmStageBean implements ServiceLocal {

                       

                          private final Logger logger = Logger.getLogger(this.getClass());

                          @EJB(beanName = "AdmBean")

                          private ServicelBeanLocal tmpBean;

                       

                          @TransactionAttribute(value = TransactionAttributeType.NEVER)

                          public boolean executeService(Map params) throws Exception {

                       

                       

                              tmpBean.setParams(params);

                             // here is calling Asychronous method

                      // right here is where I would expect it to run the following cmd asynchronously, but it seems to go block here until it is finished

                             tmpBean.invokeCommandLineApp(params);

                       

                          return true;

                          }

                       

                       

                      Here is 2nd EJB in which has Asynchronous method

                       

                      import java.util.Map;

                      import javax.ejb.Asynchronous;

                      import javax.ejb.Local;

                       

                      @Local

                      public interface ServicelBeanLocal

                      {

                          public void setParams(Map params) throws Exception;

                       

                          public void storePersistentJobProperties(Map params) throws Exception;

                       

                          @Asynchronous

                          public void invokeCommandLineApp(Map params) throws Exception;

                       

                      }

                       

                      @Stateless(name = "AdmBean")

                      public class AdmBean implements ServicelBeanLocal {

                       

                          private final Logger logger = Logger.getLogger(this.getClass());

                          @PersistenceContext()

                          private EntityManager entityManager;

                       

                      @Asynchronous

                          @TransactionAttribute(value = TransactionAttributeType.NEVER)

                          public void invokeCommandLineApp(Map params) throws Exception {

                              String filepath = (String) params.get("INPUT_FILE");

                       

                              Project project = new Project();

                              Variable var = new Environment.Variable();

                              var.setKey("tmp");

                              var.setValue(System.getProperty("java.io.tmpdir"));

                       

                              ExecTask exec = new ExecTask();

                              exec.setProject(project);

                       

                              exec.setOutputproperty("outputProp");

                              exec.setErrorProperty("errorProp");

                              exec.setResultProperty("resultProp");

                       

                              exec.addEnv(var);

                              exec.setDir(thumbnailExeFile.getParentFile());

                              exec.setExecutable(thumbnailExePath);

                              exec.createArg().setValue("-i");

                              exec.createArg().setValue(filepath);

                              //exec.createArg().setValue("-side");

                       

                              //exec.createArg().setValue("-o");

                              //exec.createArg().setValue(OutputFile);

                       

                       

                       

                             // execute ant task

                              exec.execute();

                       

                              logger.info("Output:" + project.getProperty("outputProp"));

                              logger.info("Result: " + project.getProperty("resultProp"));

                       

                              int rval = Integer.parseInt(project.getProperty("resultProp"));

                       

                      }

                       

                       

                      So I am assuming I am doing something wrong, there are no errors in log file, everything goes through fine, it just just not run off asychronously.

                       

                      Jamie

                      • 8. Re: Session bean Asynchronous Invocation
                        jaikiran pai Master

                        Jamie, sorry I forgot about this one. Did you get past this issue or are you still running into problems? If this isn't yet solved then I'll take a detailed look.

                        • 9. Re: Session bean Asynchronous Invocation
                          Jamie Blake Newbie

                          Hi Jaikiran pai,

                           

                          No I don't have it working yet, did I post enough information for you to investigate?

                           

                          Thanks

                           

                          Jamie

                          • 10. Re: Session bean Asynchronous Invocation
                            jaikiran pai Master

                            Jamie Blake wrote:

                             

                            did I post enough information for you to investigate?

                             

                            Yes, that should be enough to get started. I'll try to reproduce this in our testsuite and see what the issue is.

                            • 11. Re: Session bean Asynchronous Invocation
                              Jamie Blake Newbie

                              Jaikiran pai,

                              I made a simpler example, and deployed same ear file to glassfish 3.0.1 and jboss 6M5 to see that this works properly in glassfish but not in jboss 6.

                               

                              Here is the code:

                              package com.syncme;

                               

                              import javax.ejb.Local;

                               


                              @Local
                              public interface TestAsynchLocal {

                               

                                  public void methodAsynchronous();
                                  public void methodNonAsynchronous();
                              }

                              package com.syncme;

                               

                              import java.util.logging.Level;
                              import java.util.logging.Logger;
                              import javax.annotation.Resource;
                              import javax.ejb.Asynchronous;
                              import javax.ejb.SessionContext;
                              import javax.ejb.Stateless;

                               


                              @Stateless
                              public class TestAsynch implements  TestAsynchLocal {

                               

                                  @Resource
                                  SessionContext sctx;

                                  @Asynchronous
                                  public void methodAsynchronous() {
                                      try {
                                          System.out.println("methodAsynchronous starting");
                                          Thread.sleep(10000);
                                          System.out.println("methodAsynchronous done");
                                      } catch (InterruptedException ex) {
                                          Logger.getLogger(TestAsynch.class.getName()).log(Level.SEVERE, null, ex);
                                      }

                               


                                  }

                               

                                  public void methodNonAsynchronous() {
                                      System.out.println("methodNonAsynchronous starting");
                                    
                                      TestAsynchLocal localAsynch =  sctx.getBusinessObject(TestAsynchLocal.class);

                               

                                      localAsynch.methodAsynchronous();
                                      System.out.println("methodNonAsynchronous done");

                               

                                  }
                              }

                               

                               

                              Call from web:

                              package com.wbean;

                               

                              import com.syncme.TestAsynchLocal;
                              import javax.ejb.EJB;
                              import javax.faces.bean.ManagedBean;
                              import javax.faces.bean.SessionScoped;

                               


                              @ManagedBean(name="jsfmanbean")
                              @SessionScoped
                              public class NewJSFManagedBean {
                                  @EJB
                                  private TestAsynchLocal testAsynch;

                               

                                  /** Creates a new instance of NewJSFManagedBean */
                                  public NewJSFManagedBean() {
                                  }

                               

                                  public String Next() {
                                      return "NEXT";
                                  }

                               

                               

                               

                                  public void RunLong() {

                               

                                      testAsynch.methodNonAsynchronous();

                               


                                  }

                               

                              }

                               

                               

                              Here are the outputs:

                              Jboss 6M5 run:

                               

                              17:51:40,803 INFO  [STDOUT] methodNonAsynchronous starting
                              17:51:40,804 INFO  [STDOUT] methodAsynchronous starting
                              17:51:50,805 INFO  [STDOUT] methodAsynchronous done
                              17:51:50,805 INFO  [STDOUT] methodNonAsynchronous done

                               


                              Glassfish 3.0.1 run:
                              INFO: methodNonAsynchronous starting
                              INFO: methodNonAsynchronous done
                              INFO: methodAsynchronous starting
                              INFO: methodAsynchronous done