users@glassfish.java.net

Re: Client side Callback: javax.ejb.ConcurrentAccessException: SessionBean is executing another request

From: Miroslav Nachev <miro_at_space-comm.com>
Date: Thu, 22 May 2008 22:48:14 +0300
Here is the code:
@Stateful
public class ProductAssemblerBean
    implements ProductAssemblerRemote
{
    private final static Logger logger = Logger.getLogger(ProductAssemblerBean.class.getName());

    private boolean newCallbackRequest;
    private Callback[] newCallbacks;

    private boolean hasCallbacksResult;
    private CallbackResult callbackResult;

    public Object assemble() {
        return "miro";
    }
   
    public Callback[] clientHandle(CallbackResult callbackResult)
    {
        if(callbackResult != null)
        {
            this.callbackResult = callbackResult;
            hasCallbacksResult = true;
            return null;
        }

        if(newCallbackRequest)
        {
            newCallbackRequest = false;
            this.callbackResult = null;
            hasCallbacksResult = false;

            return newCallbacks;
        }

        return null;
    }

    public void handle(Callback[] callbacks)
        throws IOException, UnsupportedCallbackException
    {
        newCallbacks = callbacks;
        newCallbackRequest = true;

        while(!hasCallbacksResult)
        {
            Thread.yield();
        }
        hasCallbacksResult = false;

        Exception ex = callbackResult.getException();
        if(ex != null)
        {
            if(ex instanceof IOException)
                throw ((IOException)ex);

            if(ex instanceof UnsupportedCallbackException)
                throw ((UnsupportedCallbackException)ex);

            throw new RuntimeException(ex);
        }

        Callback[] resultCallbacks = callbackResult.getCallbacks();
        for(int i = 0; i < callbacks.length; i++)
        {
            callbacks[i] = resultCallbacks[i];
        }
    }

}

Client side:

    public static Object getData()
        throws Exception
    {
        ProductAssemblerRemote productAssembler = InitialContext.doLookup(ProductAssemblerRemote.class.getName());
        ClientCallback clientCallback = new ClientCallback(productAssembler);
        Object result;
        try
        {
            clientCallback.start();
            result = productAssembler.assemble();
        }
        finally
        {
            clientCallback.setWorks(false);
            clientCallback = null;
        }

        System.out.println("result: " + result);
        return result;
    }

    public static class ClientCallback
        extends Thread
    {
        private boolean works;
        private ProductAssemblerRemote productAssembler;

        public ClientCallback(ProductAssemblerRemote productAssembler)
        {
            this.productAssembler = productAssembler;
        }

        @Override
        public void run()
        {
            works = true;
            Callback[] callbacks = null;
            CallbackResult callbackResult = null;

            while(works)
            {
                Thread.yield();
                callbacks = productAssembler.clientHandle(callbackResult);
                callbackResult = null;
                if(callbacks != null && callbacks.length > 0)
                {
                    try
                    {
                        if(false)
                            throw new IOException();
                        if(false)
                            throw new UnsupportedCallbackException(null);
                        // Do something
                        ((ChoiceCallback)callbacks[0]).setSelectedIndex(7);

                        callbackResult = new CallbackResult(callbacks);
                    }
                    catch(IOException ex)
                    {
                        callbackResult = new CallbackResult(ex);
                    }
                    catch(UnsupportedCallbackException ex)
                    {
                        callbackResult = new CallbackResult(ex);
                    }
                    catch(Exception ex)
                    {
                        callbackResult = new CallbackResult(ex);
                    }
                }
            }

            System.out.println("ClientCallback stoped.");
        }

        public boolean isWorks() {
            return works;
        }

        public void setWorks(boolean works) {
            this.works = works;
        }
    }


Miroslav Nachev wrote:
Hi,

As you recommend me I am trying to implement Client side Callback. Unfortunately I have the following exception:

javax.ejb.ConcurrentAccessException: SessionBean is executing another request. [session-key: d0905b3100571f-120d8859-0]
       at com.sun.ejb.containers.StatefulSessionContainer.handleConcurrentInvocation(StatefulSessionContainer.java:2624)
       at com.sun.ejb.containers.StatefulSessionContainer._getContext(StatefulSessionContainer.java:2462)
       at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:1675)
       at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1229)
       at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:202)
       at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:117)
       at $Proxy80.assemble(Unknown Source)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154)
       at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687)
       at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227)
       at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)
       at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)
       at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)
       at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)
       at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806)
       at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)
       at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)
       at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)

Do you have another ideas how to create Client side Callback mechanism?


Regards,
Miro.