SFSB fail-over support in EJB 3.0
maxtomin May 12, 2006 2:06 AMI can not implement Stateful Session Bean fail-over, when using EJB 3.0.
I have created simple clustered SFSB and deployed the applications on 2 hosts. When one host fails, the client receives the following exception:
java.lang.RuntimeException: org.jboss.cache.ReplicationException: rsp=sender=192.168.0.26:4497, retval=null, received=false, suspected=true at org.jboss.ejb3.cache.tree.StatefulTreeCache.remove(StatefulTreeCache.java:115) at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:89) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.remoting.ReplicantsManagerInterceptor.invoke(ReplicantsManagerInterceptor.java:51) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:308) at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:104) at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82) at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828) at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681) at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358) at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:398) at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239) at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190) at org.jboss.remoting.Client.invoke(Client.java:525) at org.jboss.remoting.Client.invoke(Client.java:488) at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.remoting.ClusterChooserInterceptor.invoke(ClusterChooserInterceptor.java:74) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:55) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:65) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.stateful.StatefulClusteredProxy.invoke(StatefulClusteredProxy.java:103) at $Proxy3.inc(Unknown Source) at Main.testCounter(Main.java:63) at Main.main(Main.java:28) 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:585) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78) Caused by: org.jboss.cache.ReplicationException: rsp=sender=192.168.0.26:4497, retval=null, received=false, suspected=true at org.jboss.cache.TreeCache.callRemoteMethods(TreeCache.java:3336) at org.jboss.cache.TreeCache.callRemoteMethods(TreeCache.java:3357) at org.jboss.cache.interceptors.ReplicationInterceptor.handleReplicatedMethod(ReplicationInterceptor.java:122) at org.jboss.cache.interceptors.ReplicationInterceptor.invoke(ReplicationInterceptor.java:87) at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:41) at org.jboss.cache.interceptors.CacheStoreInterceptor.invoke(CacheStoreInterceptor.java:95) at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:4172) at org.jboss.cache.TreeCache.remove(TreeCache.java:2934) at org.jboss.cache.TreeCache.remove(TreeCache.java:2923) at org.jboss.ejb3.cache.tree.StatefulTreeCache.remove(StatefulTreeCache.java:111) at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:89) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.remoting.ReplicantsManagerInterceptor.invoke(ReplicantsManagerInterceptor.java:51) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98) at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:308) at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:104) at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82) at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828) at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681) at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358) at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:398) at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
In the similar EJB 2.1 application everithing works ok. Stateless beans on EJB 3.0 are also working with fail-over correctly.
Here is the code of the project:
Remote interface code:
import javax.ejb.Remote; import java.io.Serializable; @Remote public interface Counter extends Serializable { void init(); void inc(); int get(); }
Bean class code:
import org.jboss.annotation.ejb.Clustered; import javax.ejb.Stateful; import java.util.logging.Logger; @Stateful @Clustered public class CounterBean implements Counter { private int value = 0; public void init() { Logger.global.info("Start"); value = 0; Logger.global.info("End"); } public void inc() { Logger.global.info("Start"); ++value; Logger.global.info("End"); } public int get() { Logger.global.info("Start"); Logger.global.info("End"); return value; } }
Client code:
public class Main { private static Context ctx; public static void main(String[] args) { try { initContext(); testCounter(); } catch (Exception e) { e.printStackTrace(); } } private static void initContext() throws NamingException { ctx = new InitialContext(); } private static void testCounter() throws Exception { Counter counter = (Counter) ctx.lookup("CounterBean/remote"); for (;;) { try { counter.inc(); System.out.println("Counter = " + counter.get()); Thread.sleep(500); } catch (Exception e) { System.out.println("EXCEPTION OCCURED"); e.printStackTrace(); } } } }
jndi.properties in the client:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=192.168.0.11:1100,192.168.0.22:1100