JBoss.org Community Documentation

5.2.5. A Sample Skeleton JCA Resource Adaptor

To conclude our discussion of the JBoss JCA framework we will create and deploy a single non-transacted resource adaptor that simply provides a skeleton implementation that stubs out the required interfaces and logs all method calls. We will not discuss the details of the requirements of a resource adaptor provider as these are discussed in detail in the JCA specification. The purpose of the adaptor is to demonstrate the steps required to create and deploy a RAR in JBoss, and to see how JBoss interacts with the adaptor.

The adaptor we will create could be used as the starting point for a non-transacted file system adaptor. The source to the example adaptor can be found in the src/main/org/jboss/book/jca/ex1 directory of the book examples. A class diagram that shows the mapping from the required javax.resource.spi interfaces to the resource adaptor implementation is given in Figure 5.3, “The file system RAR class diagram”.

The file system RAR class diagram

Figure 5.3. The file system RAR class diagram


We will build the adaptor, deploy it to the JBoss server and then run an example client against an EJB that uses the resource adaptor to demonstrate the basic steps in a complete context. We'll then take a look at the JBoss server log to see how the JBoss JCA framework interacts with the resource adaptor to help you better understand the components in the JCA system level contract.

To build the example and deploy the RAR to the JBoss server deploy/lib directory, execute the following Ant command in the book examples directory.

[examples]$ ant -Dchap=jca build-chap

The deployed files include a jca-ex1.sar and a notxfs-service.xml service descriptor. The example resource adaptor deployment descriptor is shown in Example 5.1, “The nontransactional file system resource adaptor deployment descriptor.”.

<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://java.sun.com/xml/ns/"Whats_new_in_JBoss_4-J2EE_Certification_and_Standards_Compliance"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
                        http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd" version="1.5">
    <display-name>File System Adapter</display-name>
    <vendor-name>JBoss</vendor-name>
    <eis-type>FileSystem</eis-type>
    <resourceadapter-version>1.0</resourceadapter-version>
    <license>
        <description>LGPL</description>
        <license-required>false</license-required>
    </license>
    <resourceadapter>
        <resourceadapter-class>
            org.jboss.resource.deployment.DummyResourceAdapter
        </resourceadapter-class>
        <outbound-resourceadapter>
            <connection-definition>
                
                     <managedconnectionfactory-class> org.jboss.book.jca.ex1.ra.FSManagedConnectionFactory </managedconnectionfactory-class>
                  
                <config-property>
                    <config-property-name>FileSystemRootDir</config-property-name>
                    <config-property-type>java.lang.String</config-property-type>
                    <config-property-value>/tmp/db/fs_store</config-property-value>
                </config-property>
                <config-property>
                    <config-property-name>UserName</config-property-name>
                    <config-property-type>java.lang.String</config-property-type>
                    <config-property-value/>
                </config-property>
                <config-property>
                    <config-property-name>Password</config-property-name>
                    <config-property-type>java.lang.String</config-property-type>
                    <config-property-value/>
                </config-property>
                
                     <connectionfactory-interface> org.jboss.book.jca.ex1.ra.DirContextFactory </connectionfactory-interface> <connectionfactory-impl-class> org.jboss.book.jca.ex1.ra.DirContextFactoryImpl </connectionfactory-impl-class> <connection-interface> javax.naming.directory.DirContext </connection-interface> <connection-impl-class> org.jboss.book.jca.ex1.ra.FSDirContext </connection-impl-class>
                  
            </connection-definition>
            <transaction-support>NoTransaction</transaction-support>
            <authentication-mechanism>
                <authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
                <credential-interface>
                    javax.resource.spi.security.PasswordCredential
                </credential-interface>
            </authentication-mechanism>
            
                     <reauthentication-support>true</reauthentication-support>
                  
        </outbound-resourceadapter>
        <security-permission>
            <description> Read/Write access is required to the contents of the
                FileSystemRootDir </description>
            <security-permission-spec> permission java.io.FilePermission
                "/tmp/db/fs_store/*", "read,write"; 
            </security-permission-spec>
        </security-permission>
    </resourceadapter>
</connector>

Example 5.1. The nontransactional file system resource adaptor deployment descriptor.


The key items in the resource adaptor deployment descriptor are highlighted in bold. These define the classes of the resource adaptor, and the elements are:

  • managedconnectionfactory-class : The implementation of the ManagedConnectionFactory interface, org.jboss.book.jca.ex1.ra.FSManagedConnectionFactory

  • connectionfactory-interface : This is the interface that clients will obtain when they lookup the connection factory instance from JNDI, here a proprietary resource adaptor value, org.jboss.book.jca.ex1.ra.DirContextFactory. This value will be needed when we create the JBoss ds.xml to use the resource.

  • connectionfactory-impl-class : This is the class that provides the implementation of the connectionfactory-interface, org.jboss.book.jca.ex1.ra.DirContextFactoryImpl.

  • connection-interface : This is the interface for the connections returned by the resource adaptor connection factory, here the JNDI javax.naming.directory.DirContext interface.

  • connection-impl-class : This is he class that provides the connection-interface implementation, org.jboss.book.jca.ex1.ra.FSDirContext.

  • transaction-support : The level of transaction support, here defined as NoTransaction, meaning the file system resource adaptor does not do transactional work.

The RAR classes and deployment descriptor only define a resource adaptor. To use the resource adaptor it must be integrated into the JBoss application server using a ds.xml descriptor file. An example of this for the file system adaptor is shown in Example 5.2, “The notxfs-ds.xml resource adaptor MBeans service descriptor.”.

<!DOCTYPE connection-factories PUBLIC
          "-//JBoss//DTD JBOSS JCA Config 1.5//EN"
          "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">
<!--   
       The non-transaction FileSystem resource adaptor service configuration
-->
<connection-factories>
    <no-tx-connection-factory>
        <jndi-name>NoTransFS</jndi-name>
        <rar-name>jca-ex1.rar</rar-name>
        <connection-definition>
             org.jboss.book.jca.ex1.ra.DirContextFactory
        </connection-definition>
        <config-property name="FileSystemRootDir"
                         type="java.lang.String">/tmp/db/fs_store</config-property>
    </no-tx-connection-factory>
</connection-factories>

Example 5.2. The notxfs-ds.xml resource adaptor MBeans service descriptor.


The main attributes are:

  • jndi-name : This specifies where the connection factory will be bound into JNDI. For this deployment that binding will be java:/NoTransFS.

  • rar-name : This is the name of the RAR file that contains the definition for the resource we want to provide. For nested RAR files, the name would look like myapplication.ear#my.rar. In this example, it is simply jca-ex1.rar.

  • connection-definition : This is the connection factory interface class. It should match the connectionfactory-interface in the ra.xml file. Here our connection factory interface is org.jboss.book.jca.ex1.ra.DirContextFactory.

  • config-property : This can be used to provide non-default settings to the resource adaptor connection factory. Here the FileSystemRootDir is being set to /tmp/db/fs_store. This overrides the default value in the ra.xml file.

To deploy the RAR and connection manager configuration to the JBoss server, run the following:

[examples]$ ant -Dchap=jca config

The server console will display some logging output indicating that the resource adaptor has been deployed.

Now we want to test access of the resource adaptor by a J2EE component. To do this we have created a trivial stateless session bean that has a single method called echo. Inside of the echo method the EJB accesses the resource adaptor connection factory, creates a connection, and then immediately closes the connection. The echo method code is shown below.

public String echo(String arg)
{
    log.info("echo, arg="+arg);
    try {
        InitialContext ctx = new InitialContext();
        Object         ref = ctx.lookup("java:comp/env/ra/DirContextFactory");
        log.info("echo, ra/DirContextFactory=" + ref);

        DirContextFactory dcf = (DirContextFactory) ref;
        log.info("echo, found dcf=" + dcf);

        DirContext dc = dcf.getConnection();
        log.info("echo, lookup dc=" + dc);

        dc.close();
    } catch(NamingException e) {
        log.error("Failed during JNDI access", e);
    }
    return arg;
}

Example 5.3. The stateless session bean echo method code that shows the access of the resource adaptor connection factory.


The EJB is not using the CCI interface to access the resource adaptor. Rather, it is using the resource adaptor specific API based on the proprietary DirContextFactory interface that returns a JNDI DirContext object as the connection object. The example EJB is simply exercising the system contract layer by looking up the resource adaptor connection factory, creating a connection to the resource and closing the connection. The EJB does not actually do anything with the connection, as this would only exercise the resource adaptor implementation since this is a non-transactional resource.

Run the test client which calls the EchoBean.echo method by running Ant as follows from the examples directory:

[examples]$ ant -Dchap=jca -Dex=1 run-example

You'll see some output from the bean in the system console, but much more detailed logging output can be found in the server/production/log/server.log file. Don't worry if you see exceptions. They are just stack traces to highlight the call path into parts of the adaptor. To help understand the interaction between the adaptor and the JBoss JCA layer, we'll summarize the events seen in the log using a sequence diagram. Figure 5.4, “A sequence diagram illustrating the key interactions between the JBossCX framework and the example resource adaptor that result when the EchoBean accesses the resource adaptor connection factory.” is a sequence diagram that summarizes the events that occur when the EchoBean accesses the resource adaptor connection factory from JNDI and creates a connection.

A sequence diagram illustrating the key interactions between the JBossCX framework and the example resource adaptor that result when the EchoBean accesses the resource adaptor connection factory.

Figure 5.4. A sequence diagram illustrating the key interactions between the JBossCX framework and the example resource adaptor that result when the EchoBean accesses the resource adaptor connection factory.


The starting point is the client's invocation of the EchoBean.echo method. For the sake of conciseness of the diagram, the client is shown directly invoking the EchoBean.echo method when in reality the JBoss EJB container handles the invocation. There are three distinct interactions between the EchoBean and the resource adaptor; the lookup of the connection factory, the creation of a connection, and the close of the connection.

The lookup of the resource adaptor connection factory is illustrated by the 1.1 sequences of events. The events are:

  • 1, the echo method invokes the getConnection method on the resource adaptor connection factory obtained from the JNDI lookup on the java:comp/env/ra/DirContextFactory name which is a link to the java:/NoTransFS location.

  • 1.1, the DirContextFactoryImpl class asks its associated ConnectionManager to allocate a connection. It passes in the ManagedConnectionFactory and FSRequestInfo that were associated with the DirContextFactoryImpl during its construction.

  • 1.1.1, the ConnectionManager invokes its getManagedConnection method with the current Subject and FSRequestInfo.

  • 1.1.1.1, the ConnectionManager asks its object pool for a connection object. The JBossManagedConnectionPool$BasePool is get the key for the connection and then asks the matching InternalPool for a connection.

  • 1.1.1.1.1, Since no connections have been created the pool must create a new connection. This is done by requesting a new managed connection from the ManagedConnectionFactory. The Subject associated with the pool as well as the FSRequestInfo data are passed as arguments to the createManagedConnection method invocation.

  • 1.1.1.1.1.1, the ConnectionFactory creates a new FSManagedConnection instance and passes in the Subject and FSRequestInfo data.

  • 1.1.1.2, a javax.resource.spi.ConnectionListener instance is created. The type of listener created is based on the type of ConnectionManager. In this case it is an org.jboss.resource.connectionmgr.BaseConnectionManager2$NoTransactionListener instance.

  • 1.1.1.2.1, the listener registers as a javax.resource.spi.ConnectionEventListener with the ManagedConnection instance created in 1.2.1.1.

  • 1.1.2, the ManagedConnection is asked for the underlying resource manager connection. The Subject and FSRequestInfo data are passed as arguments to the getConnection method invocation.

  • The resulting connection object is cast to a javax.naming.directory.DirContext instance since this is the public interface defined by the resource adaptor.

  • After the EchoBean has obtained the DirContext for the resource adaptor, it simply closes the connection to indicate its interaction with the resource manager is complete.

This concludes the resource adaptor example. Our investigation into the interaction between the JBossCX layer and a trivial resource adaptor should give you sufficient understanding of the steps required to configure any resource adaptor. The example adaptor can also serve as a starting point for the creation of your own custom resource adaptors if you need to integrate non-JDBC resources into the JBoss server environment.