In the last few days, I struggled to implement my first JCA adapter. My goal was a solution for a transactional access to external Systems like Hadoop or Lucene from my Java EE application. As I finally succeed, I try here to answer some my own questions:
1) The Examples:
I found two examples which helped me to get started.
WildFly 10 JCA Tutorial:
The JCA tutorial from masterboss gives a good example how to implement a JCA Adapter without the need for an ra.xml file and no additional configuration in the wildfly standalone.xml. The adapter is deployed with the help of the ‘ironjacamar’ which is part of Wildfly.
Adam Biens ‘Connectorz’:
Adam Bien’s Connectorz is a more generic example of how a JCA connector could work with transaction support. Also this example needs no ra.xml file.The example is not bound to the wildfly platform only. To deploy the adapter into Wildfly, the standalone.xml file must provide a corresponding configuration section.
<subsystem xmlns="urn:jboss:domain:resource-adapters:4.0"> <resource-adapters> <resource-adapter id="imixs-archive-hadoop-genericjca-1.0.0-SNAPSHOT.rar"> <archive> imixs-archive-hadoop-genericjca-1.0.0-SNAPSHOT.rar </archive> <transaction-support>LocalTransaction</transaction-support> <connection-definitions> <connection-definition class-name="org.connectorz.files.store.GenericManagedConnectionFactory" jndi-name="java:/jca/bucket" enabled="true" use-java-context="true" pool-name="Bucket" use-ccm="true"> <config-property name="rootDirectory"> ./store/ </config-property> <pool> <min-pool-size>0</min-pool-size> <max-pool-size>10</max-pool-size> <prefill>false</prefill> <use-strict-min>false</use-strict-min> <flush-strategy>FailingConnectionOnly</flush-strategy> </pool> <security> <application/> </security> </connection-definition> </connection-definitions> </resource-adapter> </resource-adapters> </subsystem>
The advantage here is that the adapter shows more internal business logic. Also the configuration via the standalone.xml is more flexible (even if it is a bit more deployment work)
2) The Deployment
A JCA Adapter can be deployed as any other artifact. But the .jar File must be renamed into ‘.rar’! This file extension indicates the module as an JCA adapter! Otherwise the adapter will not work.
3) The JDNI Name
To verify if the deployment is correct, the Wildfly JNDI-View can be used from the Wildfly Web console to lookup the JNDI name of the module. Only when the JNDI name is there you can start with your client code…
4) The client implementation
The client code (e.g a Web module or a Ear Bundle) must not include the JCA Adapter code! For Maven projects this means that the dependecy of the corresponding maven artifacts have to be marked with scope ‘provided’. This is important to avoid class loading conflicts.
The adapter can than be injected into a servlet or a EJB with the corresponding JNDI name:
... @Resource(mappedName = "java:/jca/bucket") BucketStore bucketStore;
To make the adapter visible to the client application a wildfly specific deployment descriptor named ‘jboss-deployment-structure.xml’ is necessary.
This descriptor can be placed into the /WEB-INF/ folder for single Web modules or into the /META-INF/ root-folder for Ear bundles.
<jboss-deployment-structure> <ear-subdeployments-isolated>false</ear-subdeployments-isolated> <deployment> <dependencies> <module name="deployment.my-jca-module.rar" export="true"/> </dependencies> </deployment> </jboss-deployment-structure>
The attribute ‘export=”true”‘ is only(!) necessary for Ear bundles. And it is mandatory for Ear bundles.
The ‘jboss-deployment-structure’ did the same, as the Java EE containers did with all the Database, Mail or JMS adapters. It simply adds the code into the application classpath.
The next weeks I will continue my work on my hadoop jca adapter which will become part of the Imixs-Workflow project. See also: https://github.com/imixs/imixs-archive/tree/master/imixs-archive-hadoop-jca