⚠️ REMARK:Dear community members,
Thanks for your interest in hazelcast-ra! This project has become a Hazelcast Community project.
Hazelcast Inc. gives this project to the developers community in the hope you can benefit from it. It comes without any maintenance guarantee by the original developers but their goodwill (and time!). We encourage you to use this project however you see fit, including any type of contribution in the form of a pull request or an issue.
Feel free to visit our Slack Community for any help and feedback.
- Getting Started
- Integrating into Java EE / Jakarta EE
- Sample Code for Java EE / Jakarta EE Integration
- Configuring Resource Adapter
- Configuring a Glassfish v3 Web Application
- Configuring a Wildfly 10.1 Web Application
- Configuring a JBoss AS 5 Web Application
- Configuring a JBoss AS 7 or EAP 6 Web App
- Known Issues
Hazelcast JCA resource adapter is a system-level software driver used by a Java application to connect to an Hazelcast Cluster.
please see releases prior to v3.7 on hazelcast main repository.
As of hazelcast-ra v3.7, hazelcast-ra module has its own release cycle with initial release of v3.7
As of hazelcast-ra v3.7.3, hazelcast-ra module will require Java 8 as minimum since it uses Hazelcast IMDG v3.12.3 which also requires so.
Starting with hazelcast-ra v4.0, hazelcast-ra module will require Hazelcast 4.0+.
You can integrate Hazelcast into Java EE / Jakarta EE containers via the Hazelcast Resource Adapter (hazelcast-jca-rar-<version>.rar
). After a proper configuration, Hazelcast can participate in standard Java EE / Jakarta EE transactions.
<%@page import="javax.resource.ResourceException"%>
<%@page import="javax.transaction.*"%>
<%@page import="javax.naming.*"%>
<%@page import="javax.resource.cci.*"%>
<%@page import="java.util.*"%>
<%@page import="com.hazelcast.core.*"%>
<%@page import="com.hazelcast.jca.*"%>
<%
UserTransaction txn = null;
HazelcastConnection conn = null;
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
try {
Context context = new InitialContext();
txn = (UserTransaction) context.lookup( "java:comp/UserTransaction" );
txn.begin();
HazelcastConnectionFactory cf = (HazelcastConnectionFactory)
context.lookup ( "java:comp/env/HazelcastCF" );
conn = cf.getConnection();
TransactionalMap<String, String> txMap = conn.getTransactionalMap( "default" );
txMap.put( "key", "value" );
txn.commit();
} catch ( Throwable e ) {
if ( txn != null ) {
try {
txn.rollback();
} catch ( Exception ix ) {
ix.printStackTrace();
};
}
e.printStackTrace();
} finally {
if ( conn != null ) {
try {
conn.close();
} catch (Exception ignored) {};
}
}
%>
Sometimes Hazelcast class loader might not be able to find the classes you provide, i.e. your class loader might be different than that of Hazelcast. In this case, you need to specify the class loader through Config
to be used internally by Hazelcast.
Assume that Hazelcast is embedded in a container and you want to run your own Runnable
through IExecutorService
. Here, Hazelcast class loader and your class loader are different. Therefore, Hazelcast class loader does not know your Runnable
class.
You need to tell Hazelcast to use a specified class loader to lookup classes internally. A sample code line for this could be config.setClassLoader(getClass().getClassLoader())
.
Please see our sample application for Java EE / Jakarta EE Integration.
Deploying and configuring the Hazelcast resource adapter is no different than configuring any other resource adapter since the Hazelcast resource adapter is a standard JCA one. However, resource adapter installation and configuration is container-specific, so please consult your Java EE / Jakarta EE vendor documentation for details. The most common steps are:
- Add the
hazelcast-
version.jar
andhazelcast-jca-
version.jar
to the container's classpath. Usually there is a lib directory that is loaded automatically by the container on startup. - Deploy
hazelcast-jca-rar-
version.rar
. Usually there is some kind of a deploy directory. The name of the directory varies by container. - Make container-specific configurations when/after deploying
hazelcast-jca-rar-
version.rar
. In addition to container specific configurations, set the JNDI name for the Hazelcast resource. - Configure your application to use the Hazelcast resource. Update
web.xml
and/orejb-jar.xml
to let the container know that your application will use the Hazelcast resource, and define the resource reference. - Make the container-specific application configuration to specify the JNDI name used for the resource in the application.
To configure an example Glassfish v3 web application:
- Place the
hazelcast-
version.jar
andhazelcast-jca-
version.jar
into theGLASSFISH_HOME/glassfish/ domains/domain1/lib/ext/
folder. - Place the
hazelcast-jca-rar-
version.rar
intoGLASSFISH_HOME/glassfish/domains/domain1/autodeploy/
folder. - Add the following lines to the
web.xml
file.
<resource-ref>
<res-ref-name>HazelcastCF</res-ref-name>
<res-type>com.hazelcast.jca.ConnectionFactoryImpl</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Notice that we did not have to put sun-ra.xml
into the RAR file since it already comes with the hazelcast-ra-
version.rar
file.
If the Hazelcast resource is used from EJBs, you should configure ejb-jar.xml
for resource reference and JNDI definitions, just like for the web.xml
file.
To configure an example Wildfly 10.1 web application:
- Create the folder
<wildfly_home>/modules/system/layers/base/com/hazelcast/main
. - Place the
hazelcast-
<version>.jar
andhazelcast-jca-
<version>.jar
into the folder you created in the previous step. - Create the file
module.xml
and place it in the same folder. This file should have the following content:
<module xmlns="urn:jboss:module:1.5" name="com.hazelcast">
<resources>
<resource-root path="hazelcast-<version>.jar"/>
<resource-root path="hazelcast-jca-<version>.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.cache.api"/>
<module name="javax.resource.api"/>
<module name="javax.transaction.api"/>
<module name="org.apache.log4j"/>
<module name="sun.jdk"/>
</dependencies>
</module>
Here is the simple example of Hazelcast JCA connection with Wildfly in Docker environment:
https://github.com/hazelcast/hazelcast-docker-samples/tree/master/jca-ra
To configure a JBoss AS 5 web application:
- Place the
hazelcast-
version.jar
andhazelcast-jca-
version.jar
into theJBOSS_HOME/server/deploy/ default/lib
folder. - Place the
hazelcast-jca-rar-
version.rar
into theJBOSS_HOME/server/deploy/default/deploy
folder. - Create a
hazelcast-ds.xml
file containing the following content in theJBOSS_HOME/server/deploy/default/deploy
folder. Make sure to set therar-name
element tohazelcast-ra-
version.rar
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE connection-factories
PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"
"http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">
<connection-factories>
<tx-connection-factory>
<local-transaction/>
<track-connection-by-tx>true</track-connection-by-tx>
<jndi-name>HazelcastCF</jndi-name>
<rar-name>hazelcast-jca-rar-<version>.rar</rar-name>
<connection-definition>
javax.resource.cci.ConnectionFactory
</connection-definition>
</tx-connection-factory>
</connection-factories>
- Add the following lines to the
web.xml
file.
<resource-ref>
<res-ref-name>HazelcastCF</res-ref-name>
<res-type>com.hazelcast.jca.ConnectionFactoryImpl</res-type>
<res-auth>Container</res-auth>
</resource-ref>
- Add the following lines to the
jboss-web.xml
file.
<resource-ref>
<res-ref-name>HazelcastCF</res-ref-name>
<jndi-name>java:HazelcastCF</jndi-name>
</resource-ref>
If the Hazelcast resource is used from EJBs, you should configure ejb-jar.xml
and jboss.xml
for resource reference and JNDI definitions.
Deploying on JBoss AS 7 or JBoss EAP 6 is a straightforward process. The steps you perform are shown below. The only non-trivial step is the creation of a new JBoss module with Hazelcast libraries.
- Create the folder
<jboss_home>/modules/system/layers/base/com/hazelcast/main
. - Place the
hazelcast-
<version>.jar
andhazelcast-jca-
<version>.jar
into the folder you created in the previous step. - Create the file
module.xml
and place it in the same folder. This file should have the following content:
<module xmlns="urn:jboss:module:1.0" name="com.hazelcast">
<resources>
<resource-root path="."/>
<resource-root path="hazelcast-<version>.jar"/>
<resource-root path="hazelcast-jca-<version>.jar"/>
</resources>
<dependencies>
<module name="sun.jdk"/>
<module name="javax.api"/>
<module name="javax.resource.api"/>
<module name="javax.validation.api"/>
<module name="org.jboss.ironjacamar.api"/>
</dependencies>
</module>
At this point, you have a new JBoss module with Hazelcast in it. You can now start JBoss and deploy the hazelcast-jca-rar-
<version>.rar
file via JBoss CLI or Administration Console.
Once the Hazelcast Resource Adapter is deployed, you can start using it. The easiest way is to let a container inject ConnectionFactory
into your beans.
package com.hazelcast.examples.rar;
import com.hazelcast.core.TransactionalMap;
import com.hazelcast.jca.HazelcastConnection;
import javax.annotation.Resource;
import javax.resource.ResourceException;
import javax.resource.cci.ConnectionFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
@javax.ejb.Stateless
public class ExampleBean implements ExampleInterface {
private final static Logger log = Logger.getLogger(ExampleBean.class.getName());
@Resource(mappedName = "java:/HazelcastCF")
protected ConnectionFactory connectionFactory;
public void insert(String key, String value) {
HazelcastConnection hzConn = null;
try {
hzConn = getConnection();
TransactionalMap<String,String> txmap = hzConn.getTransactionalMap("txmap");
txmap.put(key, value);
} finally {
closeConnection(hzConn);
}
}
private HazelcastConnection getConnection() {
try {
return (HazelcastConnection) connectionFactory.getConnection();
} catch (ResourceException e) {
throw new RuntimeException("Error while getting Hazelcast connection", e);
}
}
private void closeConnection(HazelcastConnection hzConn) {
if (hzConn != null) {
try {
hzConn.close();
} catch (ResourceException e) {
log.log(Level.WARNING, "Error while closing Hazelcast connection.", e);
}
}
}
}
By default the JCA starts a new Hazelcast Server Instance. If this is not necessary, a Hazelcast Client instance can be used instead.
To use a Hazelcast Client, modify the client
property in the ra.xml file so its set to true. Also please make sure to configure a correct hazelcast client config file.
When a thread finishes without calling commit or rollback because of an error, the transaction context is leaked in the
LocalTransaction
. Calling rollback
from another thread is not possible because Hazelcast transactions do not span
multiple threads. Although resources (obtained locks) will be released automatically after timeout, this
LocalTransaction
cannot be used. In such a scenario, HazelcastTransaction#reset
method can be used to reset the
transaction.
- There is a regression in JBoss EAP 6.1.0 causing failure during Hazelcast Resource Adapter deployment. The issue is fixed in JBoss EAP 6.1.1. Please see this for additional details.