EmailLinkedInGoogle+TwitterFacebook

It is not easy, intutive or natively supported on Jboss AS 5.1 to deploy a Seam 2.2 component as a Singleton with CLUSTER scope. This requirement was an absolute must for us to ensure that a job scheduler runs on only one node in a cluster. Multiple instances of this CRON like scheduler would introduce race conditions and circumventing those in any other way would introduce unwanted code complexity. The best solution I was looking for was a support in componenets.xml where I could mark my bean as a ‘CLUSTER’ scoped. This, however was not available. Natively, Jboss supports clusterwide singletons through its HASingleton framework. A bean, in many cases an EJB, can be configured as an HASingleton either by xml configuration or through class level annotation. However this works only with object instances managed by the container. Seam runs a container within the container (Jboss) to manage its components. So decorating a seam component to use HASingleton was a long shot and as expected it proved futile.

The Solution (a.k.a Hack)

I introduced an MBean which when activated by the container will set a System variable isMasterNode=TRUE. The scheduler will then depend on checking this System variable before triggering its jobs. An MBean can easily be configured as an HASingleton. So, the cluster will ensure that only one instance of this MBean is active in the cluster. My scheduler will execute only on the node where this MBean is active. I packaged this MBean and its configuration along with the war containing seam components. Worked just fine.

MasterNodeCheckerMBean.java


package org.boni.application.mbean;

public interface MasterNodeCheckerMBean extends org.jboss.system.ServiceMBean {

}

MasterNodeChecker.java

import org.jboss.system.ServiceMBeanSupport;

public class MasterNodeChecker extends ServiceMBeanSupport implements MasterNodeCheckerMBean {
	static final String IS_MASTER_NODE = "isMasterNode";
	static final String TRUE = "true";
	static final String FALSE = "false";
	@Override
	public void startService() throws Exception {
		System.setProperty(IS_MASTER_NODE, TRUE);
		System.out.println(">>>>>>>>>>>>> (startService) IS MASTER NODE = " + System.getProperty(IS_MASTER_NODE));
	}
	@Override
	public void stopService() throws Exception {
		System.setProperty(IS_MASTER_NODE, FALSE);
		System.out.println(">>>>>>>>>>>>> (stopService) IS MASTER NODE = " + System.getProperty(IS_MASTER_NODE));
	}
	
	public boolean isMasterNode(){
		return (System.getProperty(IS_MASTER_NODE) != null && System.getProperty(IS_MASTER_NODE).equals(TRUE))?true:false;
	}
}

Additional dependency in pom.xml

		<dependency>
			<groupId>org.jboss.jbossas</groupId>
			<artifactId>jboss-as-varia</artifactId>
			<version>5.1.0.GA</version>
			<scope>provided</scope>
		</dependency>

META-INF/jboss-service.xml (That deploys MBean as an HASingleton)

<?xml version="1.0" encoding="UTF-8"?>
<server>
	<mbean code="org.boni.virtuoso.mbean.MasterNodeChecker"
		name="org.boni.virtuoso:service=MasterNodeCheckerMBean">
		<depends>jboss.ha:service=HASingletonDeployer,type=Barrier</depends>
	</mbean>
</server>

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation