HowDoIGetAnMDBSingleton

How do I get an MDB singleton?

 

There are two ways to do this, one for ejb 2.1 and one for ejb3.  If you are using 4.2 or above and you have not specified ejb 2.1, you are using ejb3.  If you are prior to 4.2 and you have not installed ejb3 either manually or through the installer, you are using ejb2.1.

 

EJB2.1

 

From 3.2.4 you would use the following in jboss.xml.  This is the easiest way is just to specify configuration name in your ejb, since singleton is already defined.

<message-driven>
<ejb-name>whatever</ejb-name>
<configuration-name>Singleton Message Driven Bean</configuration-name>
etc.

 

Before 3.2.4 you will have to add this configuration yourself:

example config

 

The predefined mdb configuration does the following.  You can adapt these same instructions either for the default messageDrivenBean configuration or you can define your own configuration and refer to it in your deployment descriptor.

 

Inside of the invoker, the MaximumSize is set to be 1.  This will cause the pool of invokers to be one, which means that only one invoker will be called at a time, making it equivalent to single-threaded.  Notice in the Singleton configuration, the container pool is still set for 100.  This is ok, because if you are only calling through with one thread at a time, the number of instances of the mdb doesn't matter(you're only going to use one at a time)

  <invoker-proxy-binding>
      <name>message-driven-bean</name>
      <invoker-mbean>default</invoker-mbean>
      <proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
      <proxy-factory-config>
        <JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
        <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
        <CreateJBossMQDestination>true</CreateJBossMQDestination>
        <!-- WARN: Don't set this to zero until a bug in the pooled executor is fixed -->
        <MinimumSize>1</MinimumSize>
        <MaximumSize>15</MaximumSize>

 

 

 

 

EJB3

EJB3 uses the resource adapter.  When using the resource adapter, you need to constrain the number of Sessions.  So you set the minimum for the sessions.  This will essentially give you a singleton.

 

you can set the maxSession in your bean with an annotation by adding

@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")

 

You can add this by default in the server/$/deploy/ejb3-interceptors-aop.xml file and add a default configuration for all MDBs by adding the following under

...This will set the default for all message driven beans.

      <annotation expr="!class(@org.jboss.annotation.ejb.DefaultActivationSpecs)">
         @org.jboss.annotation.ejb.DefaultActivationSpecs ({@javax.ejb.ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")})
      </annotation>

 

 

 

 

 

This doesn't work in a cluster?

 

Correct, because that just deals with the pooling config.

 

If you want a clustered singleton MDB you need to deploy your mdb in

deploy-hasingleton

or create your own clustered singleton deployment.