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