java ee - EJB3 llamadas concurrentes con estado de diferentes clientes
java-ee concurrency (2)
Tengo una aplicación de cliente rico que llama a un ejb remoto con estado. Estoy usando JBoss 6.0.
Implementé el cliente en dos máquinas diferentes, es decir, diferentes direcciones IP, jvms, etc.
El stateful tiene el siguiente código:
@Stateful
public class MyStateful implements MyStatefulRemote{
public void test(){
System.out.println(this);
System.out.println(Thread.currentThread());
System.out.println(Thread.currentThread().getThreadGroup());
// cpu intensive task
String value = "";
for (int j = 0; j < Integer.MAX_VALUE; j++) {
value = "" + j;
}
}
Y el cliente tiene el siguiente código:
...
String JNDI_FACADE = "MyStateful/remote";
InitialContext context = new InitialContext();
MyStatefulRemote my = (MyStatefulRemote) context.lookup(JNDI_FACADE);
my.test();
Luego, cuando ejecuto el primer cliente, el ejb ejecuta los comandos println y comienza a ejecutar el ciclo (como se esperaba). Sin embargo, cuando ejecuto el segundo cliente en una máquina diferente, el ejb no imprime nada hasta que la primera invocación al método haya finalizado. En otras palabras, parece que el bean stateful no ha sido capaz de manejar llamadas concurrentes, incluso desde diferentes clientes.
Si miramos los comandos println, podemos ver:
br.com.alta.MyStateful@61ef35
WorkerThread#6[192.168.7.58:54271]
java.lang.ThreadGroup[name=jboss,maxpri=10]
y cuando el servidor finaliza la ejecución de la primera invocación, la segunda invocación imprime el resultado:
br.com.alta.MyStateful@17539b3
WorkerThread#1[192.168.7.53:54303]
java.lang.ThreadGroup[name=jboss,maxpri=10]
Puedo observar que hay dos instancias diferentes de stateful (como se esperaba, una instancia para cada cliente), y se ejecutan en diferentes subprocesos.
Cuando uso stateless en lugar de stateful, funciona. Sin embargo, en mi aplicación necesito mantener algunos datos del cliente, y el estado parece más adecuado.
Parece que este es un error que afecta a JBoss AS 6: https://issues.jboss.org/browse/JBAS-9416
Por defecto, EJB no permite llamadas simultáneas a beans con estado. Sé que en el servidor de Weblogic puede habilitar dicha característica mediante la propiedad allow-concurrent-calls
. En JBoss, lo más probable es que deba rediseñar su arquitectura y usar beans sin estado.