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.