12 Replies Latest reply on Jun 26, 2012 11:09 AM by Paul Ferraro

    How to implement a hasingleton service in as7?

    David Robison Novice

      I am migrating some of my jboss services (SARs) from as5 to as7.1. These services were previously deployed in the deploy-hasingleton directory under as5. How do I implement a hasingleton service in as7.1?

        • 1. Re: How to implement a hasingleton service in as7?
          Tomaz Cerar Master



          I don't know the specifics about ha singleton. But support for them was added in version 7.1.0.CR1

          you can read about it in jira: https://issues.jboss.org/browse/AS7-2958


          and take a look at arq test https://github.com/jbossas/jboss-as/blob/master/testsuite/integration/clust/src/test/java/org/jboss/as/test/clustering/unmanaged/singleton/SingletonTestCase.java


          hope anything of this helps.




          • 2. Re: How to implement a hasingleton service in as7?
            Martijn Zuidhof Newbie



            We are in the same situation.. I was wondering if you had found a solution for this?


            kind regards,


            • 3. Re: How to implement a hasingleton service in as7?
              David Robison Novice

              Here is my solution:


              The MBean for the service controlling the singleton (DummySingletonSvcMBean.java)

              package com.orci.TravelTimeEngine.dummy;


              public interface DummySingletonSvcMBean {



                   * stop the service.


                  void stop();



                   * start the service.

                   * @throws Exception error


                  void start() throws Exception;




              The actual service controlling the singleton (DummySingletonSvc.java)

              package com.orci.TravelTimeEngine.dummy;


              import java.util.Collection;

              import java.util.EnumSet;


              import org.jboss.as.clustering.singleton.SingletonService;

              import org.jboss.as.clustering.singleton.election.NamePreference;

              import org.jboss.as.clustering.singleton.election.PreferredSingletonElectionPolicy;

              import org.jboss.as.clustering.singleton.election.SimpleSingletonElectionPolicy;

              import org.jboss.as.server.CurrentServiceContainer;

              import org.jboss.as.server.ServerEnvironment;

              import org.jboss.as.server.ServerEnvironmentService;

              import org.jboss.logging.Logger;

              import org.jboss.msc.service.AbstractServiceListener;

              import org.jboss.msc.service.ServiceController;

              import org.jboss.msc.service.ServiceController.Transition;

              import org.jboss.msc.service.ServiceListener;


              import com.orci.TravelTimeEngine.hibernate.utils.ThreadTransaction;


              public class DummySingletonSvc implementsDummySingletonSvcMBean {

                  private static final Logger LOG = Logger.getLogger(DummySingletonSvc.class.getName());


                  private DummySvc service;

                  private ServiceController<String> controller;



                   * {@inheritDoc}



                  public void start() throws Exception {

                      LOG.info("Starting service...");


                      String preferedNode = System.getProperty("DummySvc.PreferedNode", "tte-processor-01");

                      service = new DummySvc();

                      SingletonService<String> singleton = new SingletonService<String>(service, DummySvc.SERVICE_NAME);

                      singleton.setElectionPolicy(new PreferredSingletonElectionPolicy(new NamePreference(preferedNode + "/" + SingletonService.DEFAULT_CONTAINER), new SimpleSingletonElectionPolicy()));

                      controller = singleton.build(CurrentServiceContainer.getServiceContainer())

                              .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.getEnvInjector())




                      wait(controller, EnumSet.of(ServiceController.State.DOWN, ServiceController.State.STARTING), ServiceController.State.UP);

                      LOG.info("Start done");




                   * {@inheritDoc}



                  public void stop() {

                      LOG.info("Stopping service...");



                      wait(controller, EnumSet.of(ServiceController.State.UP, ServiceController.State.STOPPING, ServiceController.State.DOWN), ServiceController.State.REMOVED);

                      LOG.info("Stop done");




                   * Wait for the controller state.

                   * @param controller the controller

                   * @param expectedStates the expected sates

                   * @param targetState the target state

                   * @param <T> the type


                  private static <T> void wait(ServiceController<T> controller, Collection<ServiceController.State> expectedStates, ServiceController.State targetState) {

                      if (controller.getState() != targetState) {

                          ServiceListener<T> listener = new NotifyingServiceListener<T>();


                          try {

                              synchronized (controller) {

                                  while (expectedStates.contains(controller.getState())) {

                                      LOG.info(String.format("Service controller state is %s, waiting for transition to %s", controller.getState(), targetState));




                          } catch (InterruptedException e) {




                          ServiceController.State state = controller.getState();

                          if (state != targetState) {

                              throw new IllegalStateException(String.format("Failed to wait for state to transition to %s.  Current state is %s", targetState, state), controller.getStartException());





                  private static class NotifyingServiceListener<T> extends AbstractServiceListener<T> {


                      public void transition(ServiceController<? extends T> controller, Transition transition) {

                          synchronized (controller) {







              Here is the actual singleton service (DummySvc)

              package com.orci.TravelTimeEngine.AwamDataProvidor;


              import java.util.Date;

              import java.util.Timer;

              import java.util.concurrent.atomic.AtomicBoolean;


              import org.jboss.as.server.ServerEnvironment;

              import org.jboss.logging.Logger;

              import org.jboss.msc.inject.Injector;

              import org.jboss.msc.service.Service;

              import org.jboss.msc.service.ServiceName;

              import org.jboss.msc.service.StartContext;

              import org.jboss.msc.service.StartException;

              import org.jboss.msc.service.StopContext;

              import org.jboss.msc.value.InjectedValue;


              import com.orci.commons.lang.properties.PropertyFileListener;

              import com.orci.commons.lang.properties.PropertyFileWatcher;


              public class DummySvc implements Service<String>, PropertyFileListener  {

                  private static final Logger LOG = Logger.getLogger(DummySvc.class.getName());

                  public static final ServiceName SERVICE_NAME = ServiceName.JBOSS.append("orci", "DummySvc");


                  private final InjectedValue<ServerEnvironment> env = new InjectedValue<ServerEnvironment>();

                  private final AtomicBoolean started = new AtomicBoolean(false);



                   * @return the environment


                  public Injector<ServerEnvironment> getEnvInjector() {

                      return this.env;




                  public String getValue() throws IllegalStateException, IllegalArgumentException {

                      return null;




                   * {@inheritDoc}



                  public void start(StartContext ctx) throws StartException {

                      LOG.info("Starting singleton service...");

                      LOG.info("Start singleton done");




                   * {@inheritDoc}



                  public void stop(StopContext ctx) {

                      LOG.info("Stopping singleton service...");

                      LOG.info("Stop singleton done");



              Hope this helps

              • 4. Re: How to implement a hasingleton service in as7?
                VITHUN VENGOPALAN Newbie

                I'm facing the same problem here!, Even i taught of the solution David Robison has given, but I'm not sure whether its a good practice to  deploy/undeploy  ourselves (I dont actually know). Do we have any other alternative to deploy this kind of  application. In other words, what is the JBOSS recommended way of migrating application that used to be deployed in deploy-hasingleton directory. Application that wiill be active only on one machine at once.

                • 5. Re: How to implement a hasingleton service in as7?
                  Joseph Wu Newbie

                  This worked as read value from hasingleton,but how do we set value to a hasingleton? any idea?

                  Thanks a lot

                  • 6. Re: How to implement a hasingleton service in as7?
                    Wesley Janik Newbie

                    David - Thanks for the complete example on how to accomplish this.


                    Does anyone know if there is a way to accomplish the same goal without the service MBean code (DummySingletonSvc), and dependence on the Service interface in David's example?  Maybe some kind of MBean XML configuration?  I'm still fuzzy on what can and cannot be done via MBean XML, so I can't really tell if this is an option or not.  The bottom line is I'm hoping to avoid adding JBoss-specific library dependencies in my source, and instead do everything with JBoss-specific configuration.

                    • 7. Re: How to implement a hasingleton service in as7?
                      Paul Ferraro Master

                      In short, there's no way to do this without exposing JBoss specific dependencies - there is no standard API for clustered singletons.  You could get away with this in older JBoss releases by adhering to lifecycle method conventions (e.g. create(), start(), stop(), destroy()).  In constrast, AS7 uses org.jboss.msc.Service to define component lifecycle - thus the dependency on its interface.


                      Also, to address some of the confusion between the deploy-hasingleton directory approach in older JBoss releases and the SingletonService approach in AS7:

                      The deploy-hasingleton logic achieved the goal of having a target service started on only 1 node in a cluster at a time by only deploying the service on one node at any given time.  In constrast, using SingletonService in AS7, the target service will be installed on every node in the cluster, but is only ever started on one node at any given time.  This approach both simplifies deployment requirements and minimizes the time required to relocate the singleton master between nodes.

                      • 8. Re: How to implement a hasingleton service in as7?
                        Paul Ferraro Master

                        Singleton services are not meant to behave like a clustered cache.  If you want the ability to make a set of data available to all nodes in your cluster, consider using an Infinispan cache.

                        • 9. Re: How to implement a hasingleton service in as7?
                          Wesley Janik Newbie

                          Makes sense now...  Thanks for the quick response!

                          • 10. Re: How to implement a hasingleton service in as7?
                            Fred Vogt Newbie

                            David, your example doesn't redeploy cleanly.


                            There is two other MSC services that must be removed by your context listener: ServiceName SERVICE_NAME."service" and ServiceName SERVICE_NAME."singleton"


                            When the application is redeployed these services are added, if they already exist you get a duplicate service exception.

                            • 11. Re: How to implement a hasingleton service in as7?
                              Alexander Radzishevsky Newbie

                              You saved my day, Fred. Thanks a lot.

                              • 12. Re: How to implement a hasingleton service in as7?
                                Paul Ferraro Master

                                I've opened https://issues.jboss.org/browse/AS7-5073 so that we auto-remove these child services when the parent service is removed.