
Leading the Way: Payara Platform Community 7 Beta Now Fully Jakarta EE 11 Certified
We’re excited to announce that Payara Platform Community 7 Beta application server is now fully certified as Jakarta EE 11 […]
In a clustered environment, it is sometimes necessary to limit to one instance of an EJB or CDI bean for an entire cluster.
{{cta(‘4c7626f5-1e53-418e-90c8-add6e4af19c9’)}}
Currently in Java EE specification (soon to be Jakarta EE), there is no way to accomplish this. Payara Server and Payara Micro’s Clustered Singleton feature aims to easily fill in this gap.
The code below demonstrates simple clustered singleton for both EJB and CDI beans:
import fish.payara.cluster.Clustered; import javax.ejb.Singleton; import javax.enterprise.context.ApplicationScoped; @Clustered @Singleton public class MyClusteredSingletonEJB implements Serializable { /* ... */ } @Clustered @ApplicationScoped public class MyClusteredSingletonCDI implements Serializable { /* ... */ } |
Clustered Singletons are available in the Payara Platform 4.182 and Payara Platform 5.181 and later.
The @Singleton / @ApplicationScoped bean is deployed and is available to all members in the cluster. Prior to every method invocation, latest version of the bean is retrieved from a Hazelcast map. After every method invocation, possibly updated version of the bean is stored in a Hazelcast map. During this process, a Hazelcast distributed lock for the bean is optionally acquired, so there is only one method call can be executed in a particular cluster at-a-time, so no data corruption / race conditions are possible.
The main difference is that the Payara Platform Clustered Singleton implementation stores the bean in Hazelcast map across the cluster. This makes it easier to manage and eliminates the need to administer nodes that the bean is deployed to, and managing primary / backup nodes is not necessary with the Payara Platform. Other vendors have configuration requirements where to deploy the singleton, and a list of backup nodes that requires management.
Examples can be found here: clustered-singleton
Documentation can be found here: https://docs.payara.fish/documentation/payara-server/public-api/clustered-singleton.html
Annotation Parameter
|
Default
|
Description
|
---|---|---|
@Clustered(lock = DistributedLockType.INHERIT) | Yes | For EJBs, this setting enables the lock by default, or follows the @ConcurrencyManagement setting for the bean |
@Clustered(lock = DistributedLockType.LOCK) | No | distributed lock is enabled, not applicable to EJBs |
@Clustered(lock = DistributedLockType.LOCK_NONE) | No | distributed lock is disabled |
Annotation Parameter
|
Default
|
Description
|
---|---|---|
@Clustered(callPostConstructOnAttach = true|false) | true | Controls whether more than one instance calls postConstruct() |
@Clustered(callPreDestoyOnDetach = true|false) | true | controls whether more than one instance calls preDestroy() |
@Clustered(keyName = “XXX”) | bean name | sets the key for the Hazelcast map under which the bean is stored |
With persistent timers (default), they execute only on a single node in a cluster, so they work correctly with Clustered Singletons
Care must be taken in this scenario. By default, @PostConsctuct is called for every instance in the cluster for these beans. This behavior needs to be disabled by using @Clustered(callPostConstructOnAttach = false) and possibly callPreDestoyOnDetach = false as well, so only the @PostConstruct method will be called only once per cluster. @Observed @Initialized methods are called for every instance in the cluster. The only valid method for cluster-wide initialization is @PostConstruct method configured as described above.
Transactions behave the same way for Clustered beans as non-clustered. Since all calls are local, and locks work in the same way, there is no behavioural differences.
Since there are no default locks for CDI, @Clustered CDI @ApplicationScoped beans do not have distributed locks on by default.
It is highly recommended to enable distributed locks for CDI Clustered beans: @Clustered(lock = DistributedLockType.LOCK) so there is no chance of race condition / data corruption for CDI Clustered beans.
glassfish-ejb-jar.xml have additional elements described below. The elements have the same meaning and work the same way as annotation parameters described above.
Clustered Singleton elements are added to glassfish-ejb-jar.xml as follows:
<glassfish-ejb-jar> <enterprise-beans> <ejb> ... additional elements ... </ejb> </enterprise-beans> </glassfish-ejb-jar>
Additional elements:
<clustered-bean>true|false</clustered-bean> <clustered-key-name>key-name</clustered-key-name> <clustered-lock-type>inherit|none</clustered-lock-type> <clustered-attach-postconstruct>true|false</clustered-attach-postconstruct> <clustered-detach-predestroy>true|false</clustered-detach-predestroy>
Share:
We’re excited to announce that Payara Platform Community 7 Beta application server is now fully certified as Jakarta EE 11 […]
Enterprise Java applications power global commerce, healthcare, government and countless other industries. These systems must be scalable, secure and […]
May 2025 marks a monumental milestone in software development: Java turns 30. The impact of this language on the […]
Excellent. Very nice 🙂 Would be smarter with an example using a Docker – MySQL but anyway thanks for the tips.