I've a web application with EJB 3.1 and CDI beans running on Wildfly 9 app server. I've read Jboss documentation for installing and deploying HA standalone cluster environment and as per JBoss documentation all EJBs must annotated with @Cluster annotation for distribution among different cluster nodes. My question here is, do I need to annotate also my CDI beans the same way I do with EJBs ? or I need only to define the <Distributable /> tag on my web.xml and the container will handle all CDI beans as distributed objects?
1 Answers
Clustering, from a bean perspective is a concern where state matters. Think about it: if a bean doesn't hold state, what would be the purpose of replicating it across a cluster?
That brings us now to the question of what you'll stand to gain from a CDI bean that's replicated across a cluster.
A
@RequestScopedCDI bean doesn't need to go across nodes in a cluster: it's created on-demand and doesn't live beyond a single HTTP request. There's not too much of a case to be made for it to be replicated across a clusterA
@SessionScopedCDI bean will stand to benefit from replication because it contains precious cargo: session information. When a node in a cluster dies, the application stands to benefit from being able to migrate that bean to another node. But this scope is tied to the HTTP session, which is being replicated by a separate mechanism altogether and should take care of replicating the data in the bean independently of the@Clusterableannotation. Remember that EJBs, not even@Statefulare not connected to the HTTP sessionA
@ViewScopedbean is also tied to the HTTP session, so what's good for the@SessionScopedbean will also apply here.
The summary here is that whatever mechanism is responsible for replicating sessions in your cluster should suffice for CDI beans that need to be replicated. @Clusterable wouldn't apply here
EDIT: A little more digging in the CDI spec, and it backs up my hypothesis: all your CDI bean needs to do is be able to support vanilla session activation and passivation, i.e. be Serializable, and you should be fine:
6.6.1. Passivation capable beans
A bean is called passivation capable if the container is able to temporarily transfer the state of any idle instance to secondary storage.
As defined by the EJB specification, a stateful session beans is passivation capable if:
interceptors and decorators of the bean are passivation capable, and,
the stateful session bean does not have the passivationCapable flag set to false.
As defined by the EJB specification, a stateless session bean or a singleton session bean is not passivation capable.
A managed bean is passivation capable if and only if the bean class is serializable and all interceptors and decorators of the bean are passivation capable.
A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime.
A producer field is passivation capable if and only if it never refers to a value which is not passivation capable at runtime.