Hello.
My app is EAR running on JBoss 4.2.2 containing:
- Stateless Session Bean
- JSF-based web-app
SLSB is able to create/start/stop ejb.Timer, and has method annotated with @Timeout as
well.
Web-app is makes JNDI lookup to acquire bean's stub and perform it's start() and
stop() methods.
Now, my goal is to move this EAR to cluster and assure that only one instance of
"timed" SLSB is active.
So I've established two-node cluster on single machine using ServiceBindingManager in
jboss-service.xml and replaced HSQL with PostgreSQL.
I'm pretty sure my cluster partition is working properly.
Then I modified my app by adding @Clusterd and
@Depends("jboss.ha:service=HASingletonDeployer,type=Barrier") annotations on ejb
and switching from local JDNI to HA-JNDI lookup in my web-app, which now looks like this:
| ...
| import pw.test.interfaces.ITimer;
| public class TestTimerManagedBean {
|
| private ITimer timer;
|
| private void lookup() {
| Properties jndiProperties = new Properties();
| jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
| jndiProperties.put(Context.URL_PKG_PREFIXES,
"jboss.naming:org.jnp.interfaces");
| jndiProperties.setProperty("jnp.partitionName",
"pw_partition"); // partition's name
|
| Context context;
| try {
| context = new InitialContext(jndiProperties);
| this.timer = (ITimer)context.lookup("testEar/TestTimerBean/remote");
| } catch (NamingException e) {
| // TODO Auto-generated catch block
| e.printStackTrace();
| }
| }
|
| public void start() {
| this.lookup();
|
| if (this.timer != null) {
| this.timer.start();
| }
| }
|
| public void stop() {
| this.lookup();
|
| if (this.timer != null) {
| this.timer.stop();
| }
| }
| }
|
Problem description.
====================
Use case:
1. start cluster.
Partition consists of:
- node1 (ports: web=8180, JNDI=1199, HA-JNDI=1200) <-- master node
- node2 (ports: web=8280, JNDI=1299, HA-JNDI=1300)
2. place ear in /all/farm of node1.
Node1 deploys and starts SLSB, Node2 deploys SLSB but doesn't start it.
As far as I can tell, it's correct behaviour (effect of using @Depends annotation).
Here is what JNDIView shows on node1 (there are no such entries on node2's JNDIView,
it's ok i suppose):
| +- testEar (class: org.jnp.interfaces.NamingContext)
| | +- TestTimerBean (class: org.jnp.interfaces.NamingContext)
| | | +- local (proxy: $Proxy84 implements interface
pw.test.interfaces.ITestTimerLocal,interface org.jboss.ejb3.JBossProxy,interface
javax.ejb.EJBLocalObject)
| | | +- remote (proxy: $Proxy83 implements interface
pw.test.interfaces.ITestTimerRemote,interface org.jboss.ejb3.JBossProxy,interface
javax.ejb.EJBObject)
|
3. In web-browser i go to web-app on node1:
http://localhost:8180/TestTimerWeb, and
successfully lookup SLSB and start/stop timer on node1. When i kill node1, SLSB instance
on node2 is started and continues tasks (failover).
4. In web-browser i go to web-app on node2:
http://localhost:8280/TestTimerWeb, and here
my problem is. Some SLSB is looked-up, but when i try to invoke some methods on it, i get
exception:
| 2009-05-29 13:24:26,778 ERROR [javax.enterprise.resource.webcontainer.jsf.application]
java.lang.NullPointerException
| javax.faces.el.EvaluationException: java.lang.NullPointerException
| at
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
| at
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
| at javax.faces.component.UICommand.broadcast(UICommand.java:387)
| at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
| at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
| at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
| at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
| at
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
| at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
| at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
| at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
| at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
| at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
| at
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
| at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
| at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
| at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
| at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:173)
| at
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
| at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
| at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
| at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
| at
org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
| at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
| at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
| at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
| at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
| at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
| at java.lang.Thread.run(Thread.java:619)
| Caused by: java.lang.NullPointerException
| at
org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
| at
org.jboss.aspects.remoting.ReplicantsManagerInterceptor.invoke(ReplicantsManagerInterceptor.java:51)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
| at
org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
| at
org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:108)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
| at
org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
| at
org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
| at
org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:280)
| at
org.jboss.ejb3.remoting.IsLocalInterceptor.invokeLocal(IsLocalInterceptor.java:81)
| at
org.jboss.ejb3.remoting.ClusteredIsLocalInterceptor.invoke(ClusteredIsLocalInterceptor.java:53)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
| at
org.jboss.ejb3.stateless.StatelessClusteredProxy.invoke(StatelessClusteredProxy.java:113)
| at $Proxy83.start(Unknown Source)
| at pw.test.TestTimerManagedBean.start(TestTimerManagedBean.java:40)
| 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 org.apache.el.parser.AstValue.invoke(AstValue.java:131)
| at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
| at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
| at
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
| ... 28 more
|
For some reason, HA-JNDI lookup performed by web-app on node2 is optimized to local JNDI
lookup even when SLSB on this node is not started.
The only solution i've found is to edit /all/deploy/ejb3-interceptors-aop.xml and get
rid of interceptors: IsLocalInterceptor and ClusteredIsLocalInterceptor.
This soulution is too intrusive, and i'm affraid there can be some negative
consequences in future.
My question: is it possible to bypass this behaviour? I'd like to achieve this
scenario:
1. There is only one active(started) SLSB that manages my ejb.timer in entire cluster.
Let's say it would be node1 in partition.
2. Web-app controlling SLSB is present on all nodes, and regardles from which node
i'll run it, it will always find started SLSB on master node.
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4234112#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...