JBoss.orgCommunity Documentation

JBoss AS 6.0 JCA Guide

JCA with JBoss Application Server 6


I. Introduction
1. JCA Introduction
1.1. JCA Overview
1.2. What's New
II. Configuration
2. Use Alternative Databases with JBoss AS
2.1. How to Use Alternative Databases
2.2. Install JDBC Drivers
2.2.1. Special notes on Sybase
2.2.2. Configuring JDBC DataSources
2.3. Creating a DataSource for the External Database
2.4. Common configuration for DataSources and ConnectionFactorys
2.4.1. General
2.4.2. XA
2.4.3. Security parameters
2.5. Change Database for the JMS Services
2.6. Support Foreign Keys in CMP Services
2.7. Specify Database Dialect for Java Persistence API
2.8. Change Other JBoss AS Services to Use the External Database
2.8.1. The Easy Way
2.8.2. The More Flexible Way
2.9. A Special Note About Oracle DataBases
2.10. DataSource configuration
2.11. Parameters specific for java.sql.Driver usage
2.12. Parameters specific for javax.sql.XADataSource usage
2.13. Common DataSource parameters
2.14. Generic Datasource Sample
2.15. Configuring a DataSource for remote usage
2.16. Configuring a DataSource to use login modules
3. Pooling
3.1. Strategy
3.2. Transaction stickness
3.3. Workaround for Oracle
3.4. Pool Access
3.5. Pool Filling
3.6. Idle Connections
3.7. Dead connections
3.7.1. Valid connection checking
3.7.2. Errors during SQL queries
3.7.3. Changing/Closing/Flushing the pool
3.7.4. Other pooling
III. Reference
4. Connectors on JBoss
4.1. An Overview of the JBoss JCA Architecture
4.1.1. BaseConnectionManager2 MBean
4.1.2. RARDeployment MBean
4.1.3. JBossManagedConnectionPool MBean
4.1.4. CachedConnectionManager MBean
4.1.5. A Sample Skeleton JCA Resource Adaptor
4.2. XA Recovery in the JCA layer
4.2.1. New -ds.xml file
4.2.2. Minimal changes
4.2.3. Availability

For the JBoss Application Server and our applications to use the external database, we also need to install the database's JDBC driver. The JDBC driver is a JAR file, which you'll need to copy into your JBoss AS's <JBoss_Home>/server/all/lib directory. Replace all with the server configuration you are using if needed. This file is loaded when JBoss starts up. So if you have the JBoss AS running, you'll need to shut down and restart. The availability of JDBC drivers for different databases are as follows.

Some of the services in JBoss uses null values for the default tables that are created. Sybase Adaptive Server should be configured to allow nulls by default.

sp_dboption db_name, "allow nulls by default", true

Refer the sybase manuals for more options.

Enable JAVA services

To use any java service like JMS, CMP, timers etc. configured with Sybase, java should be enabled on Sybase Adaptive Server. To do this use:

sp_configure "enable java",1

Refer to the sybase manuals for more information.

If java is not enabled you might see this exception being thrown when you try to use any of the above services.

com.sybase.jdbc2.jdbc.SybSQLException: Cannot run this command because Java services are not enabled. A user with System Administrator (SA) role must reconfigure the system to enable Java

CMP Configuration

To use Container Managed Persistence for user defined Java objects with Sybase Adaptive Server Enterprise the java classes should be installed in the database. The system table 'sysxtypes' contains one row for each extended, Java-SQL datatype. This table is only used for Adaptive Servers enabled for Java. Install java classes using the installjava program.

installjava -f <jar-file-name> -S<sybase-server> -U<super-user> -P<super-pass> -D<db-name>

Refer the installjava manual in Sybase for more options.

Rather than configuring the connection manager factory related MBeans discussed in the previous section via a mbean services deployment descriptor, JBoss provides a simplified datasource centric descriptor. This is transformed into the standard jboss-service.xml MBean services deployment descriptor using a XSL transform applied by the org.jboss.deployment.XSLSubDeployer included in the jboss-jca.sar deployment. The simplified configuration descriptor is deployed the same as other deployable components. The descriptor must be named using a *-ds.xml pattern in order to be recognized by the XSLSubDeployer.

The schema for the top-level datasource elements of the *-ds.xml configuration deployment file is shown in Figure 2.1, “The simplified JCA DataSource configuration descriptor top-level schema elements”.


Multiple datasource configurations may be specified in a configuration deployment file. The child elements of the datasources root are:






Elements that are common to all datasources include:

  • jndi-name: The JNDI name under which the DataSource wrapper will be bound. Note that this name is relative to the java:/ context, unless use-java-context is set to false. DataSource wrappers are not usable outside of the server VM, so they are normally bound under the java:/, which isn't shared outside the local VM.

  • use-java-context: If this is set to false the the datasource will be bound in the global JNDI context rather than the java: context.

  • user-name: This element specifies the default username used when creating a new connection. The actual username may be overridden by the application code getConnection parameters or the connection creation context JAAS Subject.

  • password: This element specifies the default password used when creating a new connection. The actual password may be overridden by the application code getConnection parameters or the connection creation context JAAS Subject.

  • application-managed-security: Specifying this element indicates that connections in the pool should be distinguished by application code supplied parameters, such as from getConnection(user, pw).

  • security-domain: Specifying this element indicates that connections in the pool should be distinguished by JAAS Subject based information. The content of the security-domain is the name of the JAAS security manager that will handle authentication. This name correlates to the JAAS login-config.xml descriptor application-policy/name attribute.

  • security-domain-and-application: Specifying this element indicates that connections in the pool should be distinguished both by application code supplied parameters and JAAS Subject based information. The content of the security-domain is the name of the JAAS security manager that will handle authentication. This name correlates to the JAAS login-config.xml descriptor application-policy/name attribute.

  • min-pool-size: This element specifies the minimum number of connections a pool should hold. These pool instances are not created until an initial request for a connection is made. This default to 0.

  • max-pool-size: This element specifies the maximum number of connections for a pool. No more than the max-pool-size number of connections will be created in a pool. This defaults to 20.

  • blocking-timeout-millis: This element specifies the maximum time in milliseconds to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for a permit for a connection, and will never throw an exception if creating a new connection takes an inordinately long time. The default is 5000.

  • idle-timeout-minutes: This element specifies the maximum time in minutes a connection may be idle before being closed. The actual maximum time depends also on the IdleRemover scan time, which is 1/2 the smallest idle-timeout-minutes of any pool.

  • new-connection-sql: This is a SQL statement that should be executed when a new connection is created. This can be used to configure a connection with database specific settings not configurable via connection properties.

  • check-valid-connection-sql: This is a SQL statement that should be run on a connection before it is returned from the pool to test its validity to test for stale pool connections. An example statement could be: select count(*) from x.

  • exception-sorter-class-name: This specifies a class that implements the org.jboss.resource.adapter.jdbc.ExceptionSorter interface to examine database exceptions to determine whether or not the exception indicates a connection error. Current implementations include:

    • org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter

    • org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter

    • org.jboss.resource.adapter.jdbc.vendor.SybaseExceptionSorter

    • org.jboss.resource.adapter.jdbc.vendor.InformixExceptionSorte

  • valid-connection-checker-class-name: This specifies a class that implements the org.jboss.resource.adapter.jdbc.ValidConnectionChecker interface to provide a SQLException isValidConnection(Connection e) method that is called with a connection that is to be returned from the pool to test its validity. This overrides the check-valid-connection-sql when present. The only provided implementation is org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker.

  • track-statements: This boolean element specifies whether to check for unclosed statements when a connection is returned to the pool. If true, a warning message is issued for each unclosed statement. If the log4j category org.jboss.resource.adapter.jdbc.WrappedConnection has trace level enabled, a stack trace of the connection close call is logged as well. This is a debug feature that can be turned off in production.

  • prepared-statement-cache-size: This element specifies the number of prepared statements per connection in an LRU cache, which is keyed by the SQL query. Setting this to zero disables the cache.

  • depends: The depends element specifies the JMX ObjectName string of a service that the connection manager services depend on. The connection manager service will not be started until the dependent services have been started.

  • type-mapping: This element declares a default type mapping for this datasource. The type mapping should match a type-mapping/name element from standardjbosscmp-jdbc.xml.

Additional common child elements for both no-tx-datasource and local-tx-datasource include:

  • connection-url: This is the JDBC driver connection URL string, for example, jdbc:hsqldb:hsql://localhost:1701.

  • driver-class: This is the fully qualified name of the JDBC driver class, for example, org.hsqldb.jdbcDriver.

  • connection-property: The connection-property element allows you to pass in arbitrary connection properties to the java.sql.Driver.connect(url, props) method. Each connection-property specifies a string name/value pair with the property name coming from the name attribute and the value coming from the element content.

Elements in common to the local-tx-datasource and xa-datasource are:

  • transaction-isolation: This element specifies the java.sql.Connection transaction isolation level to use. The constants defined in the Connection interface are the possible element content values and include:

    • TRANSACTION_READ_UNCOMMITTED

    • TRANSACTION_READ_COMMITTED

    • TRANSACTION_REPEATABLE_READ

    • TRANSACTION_SERIALIZABLE

    • TRANSACTION_NONE

  • no-tx-separate-pools: The presence of this element indicates that two connection pools are required to isolate connections used with JTA transaction from those used without a JTA transaction. The pools are lazily constructed on first use. Its use case is for Oracle (and possibly other vendors) XA implementations that don't like using an XA connection with and without a JTA transaction.

The unique xa-datasource child elements are:

  • track-connection-by-tx: Specifying a true value for this element makes the connection manager keep an xid to connection map and only put the connection back in the pool when the transaction completes and all the connection handles are closed or disassociated (by the method calls returning). As a side effect, we never suspend and resume the xid on the connection's XAResource. This is the same connection tracking behavior used for local transactions.

    The XA spec implies that any connection may be enrolled in any transaction using any xid for that transaction at any time from any thread (suspending other transactions if necessary). The original JCA implementation assumed this and aggressively delisted connections and put them back in the pool as soon as control left the EJB they were used in or handles were closed. Since some other transaction could be using the connection the next time work needed to be done on the original transaction, there is no way to get the original connection back. It turns out that most XADataSource driver vendors do not support this, and require that all work done under a particular xid go through the same connection.

  • xa-datasource-class: The fully qualified name of the javax.sql.XADataSource implementation class, for example, com.informix.jdbcx.IfxXADataSource.

  • xa-datasource-property: The xa-datasource-property element allows for specification of the properties to assign to the XADataSource implementation class. Each property is identified by the name attribute and the property value is given by the xa-datasource-property element content. The property is mapped onto the XADataSource implementation by looking for a JavaBeans style getter method for the property name. If found, the value of the property is set using the JavaBeans setter with the element text translated to the true property type using the java.beans.PropertyEditor for the type.

  • isSameRM-override-value: A boolean flag that allows one to override the behavior of the javax.transaction.xa.XAResource.isSameRM(XAResource xaRes) method behavior on the XA managed connection. If specified, this value is used unconditionally as the isSameRM(xaRes) return value regardless of the xaRes parameter.

The failover options common to ha-xa-datasource and ha-local-tx-datasource are:

  • url-delimeter: This element specifies a character used to separate multiple JDBC URLs.

  • url-property: In the case of XA datasources, this property specifies the name of the xa-datasource-property that contains the list of JDBC URLs to use.

JBoss AS connects to relational databases via datasources. These datasource definitions can be found in the <JBoss_Home>/server/all/deploy directory. The datasource definitions are deployable just like WAR and EAR files. The datasource files can be recognized by looking for the XML files that end in *-ds.xml.

The following code snippet shows the mysql-ds.xml file as an example. All the other *-ds.xml files are very similiar. You will need to change the connection-url, as well as the user-name / password, to fit your own database server installation.


<datasources>
<local-tx-datasource>
<jndi-name>MySqlDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/jboss</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>jbossuser</user-name>
<password>jbosspass</password>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<!-- should only be used on drivers after 3.22.1 with "ping" support
<valid-connection-checker-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker
</valid-connection-checker-class-name>
-->
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
<!-- sql to call on an existing pooled connection when it is obtained from pool - 
 MySQLValidConnectionChecker is preferred for newer drivers
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
 -->
   
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
   <metadata>
 <type-mapping>mySQL</type-mapping>
 </metadata>
 </local-tx-datasource>
    
</datasources>

Once you customized the *-ds.xml file to connect to your external database, you need to copy it to the <JBoss_Home>/server/all/deploy directory. The database connection is now available through the JNDI name specified in the *-ds.xml file.

JCA Login Modules - are used to inject security configuration into the connection when configured

The Java Persistence API (JPA) entity manager can save EJB3 entity beans to any backend database. Hibernate provides the JPA implementation in JBoss AS. Hibernate has a dialect auto-detection mechanism that works for most databases including the dialects for databases referenced in this appendix which are listed below. If a specific dialect is needed for alternative databases, you can configure the database dialect in the <JBoss_Home>/server/all/deploy/ejb3.deployer/META-INF/persistence.properties file. You need to un-comment the hibernate.dialect property and change its value to the following based on the database you setup. For a complete list of dialects, refer to the Hibernate Reference Guide, Chapter 3, Section 4.1 SQL Dialects.

Besides JMS, CMP, and JPA, we still need to hook up the rest of JBoss services with the external database. There are two ways to do it. One is easy but inflexible. The other is flexible but requires more steps. Now, let's discuss those two approaches respectively.

The easy way is just to change the JNDI name for the external database to DefaultDS. Most JBoss services are hard-wired to use the DefaultDS by default. So, by changing the datasource name, we do not need to change the configuration for each service individually.

To change the JNDI name, just open the *-ds.xml file for your external database, and change the value of the jndi-name property to DefaultDS. For instance, in mysql-ds.xml, you'd change MySqlDS to DefaultDS and so on. You will need to remove the <JBoss_Home>/server/all/deploy/hsqldb-ds.xml file after you are done to avoid duplicated DefaultDS definition.

In the jms/*-jdbc2-service.xml file, you should also change the datasource name in the depends tag for the PersistenceManagers MBean to DefaultDS. For instance, for mysql-jdbc2-service.xml file, we change the MySqlDS to DefaultDS.

The easy way is just to change the JNDI name for the external database to DefaultDS. Most JBoss services are hard-wired to use the DefaultDS by default. So, by changing the datasource name, we do not need to change the configuration for each service individually.

To change the JNDI name, just open the *-ds.xml file for your external database, and change the value of the jndi-name property to DefaultDS. For instance, in mysql-ds.xml, you'd change MySqlDS to DefaultDS and so on. You will need to remove the <JBoss_Home>/server/all/deploy/hsqldb-ds.xml file after you are done to avoid duplicated DefaultDS definition.

In the jms/*-jdbc2-service.xml file, you should also change the datasource name in the depends tag for the PersistenceManagers MBean to DefaultDS. For instance, for mysql-jdbc2-service.xml file, we change the MySqlDS to DefaultDS.


.. ...
<mbean code="org.jboss.mq.pm.jdbc2.PersistenceManager"
       name="jboss.mq:service=PersistenceManager"%gt;
  <depends optional-attribute-name="ConnectionManager">
    jboss.jca:service=DataSourceBinding,name=DefaultDS
  </depends>
... ...

Changing the external datasource to DefaultDS is convenient. But if you have applications that assume the DefaultDS always points to the factory-default HSQL DB, that approach could break your application. Also, changing DefaultDS destination forces all JBoss services to use the external database. What if you want to use the external database only on some services?

A safer and more flexible way to hook up JBoss AS services with the external datasource is to manually change the DefaultDS in all standard JBoss services to the datasource JNDI name defined in your *-ds.xml file (e.g., the MySqlDS in mysql-ds.xml etc.). Below is a complete list of files that contain DefaultDS. You can update them all to use the external database on all JBoss services or update some of them to use different combination of datasources for different services.

In our setup discussed in this chapter, we rely on the JBoss AS to automatically create needed tables in the external database upon server startup. That works most of the time. But for databases like Oracle, there might be some minor issues if you try to use the same database server to back more than one JBoss AS instance.

The Oracle database creates tables of the form schemaname.tablename. The TIMERS and HILOSEQUENCES tables needed by JBoss AS would not get created on a schema if the table already exists on a different schema. To work around this issue, you need to edit the <JBoss_Home>/server/all/deploy/ejb-deployer.xml file to change the table name from TIMERS to something like schemaname2.tablename.


<mbean code="org.jboss.ejb.txtimer.DatabasePersistencePolicy" 
name="jboss.ejb:service=EJBTimerService,persistencePolicy=database">
<!-- DataSourceBinding ObjectName -->
<depends optional-attribute-name="DataSource">
 jboss.jca:service=DataSourceBinding,name=DefaultDS
</depends>
<!-- The plugin that handles database persistence -->
<attribute name="DatabasePersistencePlugin">
org.jboss.ejb.txtimer.GeneralPurposeDatabasePersistencePlugin
</attribute>
<!-- The timers table name -->
<attribute name="TimersTable">TIMERS</attribute>
</mbean> 

Similarly, you need to change the <JBoss_Home>/server/all/deploy/uuid-key-generator.sar/META-INF/jboss-service.xml file to change the table name from HILOSEQUENCES to something like schemaname2.tablename as well.

<!-- HiLoKeyGeneratorFactory -->
<mbean code="org.jboss.ejb.plugins.keygenerator.hilo.HiLoKeyGeneratorFactory"
name="jboss:service=KeyGeneratorFactory,type=HiLo">
	
<depends>jboss:service=TransactionManager</depends>
	
<!-- Attributes common to HiLo factory instances -->
	
<!-- DataSource JNDI name -->
<depends optional-attribute-name="DataSource">jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
	
<!-- table name -->
<attribute name="TableName">HILOSEQUENCES</attribute>

From JBoss AS 3.2.6 and above, track-statements has a new option:


<track-statements>nowarn</track-statements

This option closes Statements and ResultSets without a warning. It is also the new default value.

The purpose is to workaround questionable driver behavior where the driver applies auto-commit semantics to local transactions.

Connection c = dataSource.getConnection(); // auto-commit == false

PreparedStatement ps1 = c.prepareStatement(...);
ResultSet rs1 = ps1.executeQuery();
PreparedStatement ps2 = c.prepareStatement(...);
ResultSet rs2 = ps2.executeQuery();

Assuming the prepared statements are the same. For some drivers, ps2.executeQuery() will automatically close rs1 so we actually need two real prepared statements behind the scenes. This *should* only be for the auto-commit semantic where re-running the query starts a new transaction automatically. For drivers that follow the spec, you can set it to true to share the same real prepared statement.


<datasources>
<local-tx-datasource>
<jndi-name>GenericDS</jndi-name>
<connection-url>[jdbc: url for use with Driver class]</connection-url>
<driver-class>[fully qualified class name of java.sql.Driver implementation]</driver-class>
<user-name>x</user-name>
<password>y</password>
<!-- you can include connection properties that will get passed in 
the DriverManager.getConnection(props) call-->
<!-- look at your Driver docs to see what these might be -->
<connection-property name="char.encoding">UTF-8</connection-property>
<transaction-isolation>TRANSACTION_SERIALIZABLE</transaction-isolation>
    
<!--pooling parameters-->
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
                    
<!-- sql to call on an existing pooled connection when it is obtained from pool 
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
-->
                    
<set-tx-query-timeout/>
<query-timeout>300</query-timeout> <!-- maximum of 5 minutes for queries -->
    
<!-- pooling criteria.  USE AT MOST ONE-->
<!--  If you don't use JAAS login modules or explicit login 
getConnection(usr,pw) but rely on user/pw specified above, 
don't specify anything here -->

<!-- If you supply the usr/pw from a JAAS login module -->
<security-domain>MyRealm</security-domain>
                    
<!-- if your app supplies the usr/pw explicitly getConnection(usr, pw) -->
<application-managed-security/>

<!--Anonymous depends elements are copied verbatim into the ConnectionManager mbean config-->
<depends>myapp.service:service=DoSomethingService</depends>
                    
</local-tx-datasource>
                    
<!-- you can include regular mbean configurations like this one -->
<mbean code="org.jboss.tm.XidFactory" 
name="jboss:service=XidFactory">
<attribute name="Pad">true</attribute>
</mbean>

<!-- Here's an xa example -->
<xa-datasource>
<jndi-name>GenericXADS</jndi-name>
<xa-datasource-class>[fully qualified name of class implementing javax.sql.XADataSource goes here]</xa-datasource-class>
<xa-datasource-property name="SomeProperty">SomePropertyValue</xa-datasource-property>
<xa-datasource-property name="SomeOtherProperty">SomeOtherValue</xa-datasource-property>

<user-name>x</user-name>
<password>y</password>
<transaction-isolation>TRANSACTION_SERIALIZABLE</transaction-isolation>

<!--pooling parameters-->
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->

<!-- sql to call on an existing pooled connection when it is obtained from pool 
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
-->

<!-- pooling criteria.  USE AT MOST ONE-->
<!--  If you don't use JAAS login modules or explicit login 
getConnection(usr,pw) but rely on user/pw specified above, 
don't specify anything here -->

<!-- If you supply the usr/pw from a JAAS login module -->
<security-domain/>

<!-- if your app supplies the usr/pw explicitly getConnection(usr, pw) -->
<application-managed-security/>

</xa-datasource>

</datasources>

Add the security-domain parameter to the *-ds.xml file.


<datasources>
<local-tx-datasource>
...
<security-domain>MyDomain</security-domain>
...
</local-tx-datasource>
</datasources>

Add an application-policy to the login-config.xml file. The authentication section should include the configuration for your login-module. For example, if you want to encrypt the database password, use the SecureIdentityLoginModule login module.


<application-policy name="MyDomain">
<authentication>
<login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
<module-option name="username">scott</module-option>
<module-option name="password">-170dd0fbd8c13748</module-option>
<module-option name="managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=OracleDSJAAS</module-option>
</login-module>
</authentication>
</application-policy>

In case you plan to fetch the data source connection from a web application, make sure authentication is turned on for the web application. This is in order for the Subject to be populated. If you wish for users to be able to connect anonymously, an additional login module needs to be added to the application-policy, in order to populate the security credentials. Add the UsersRolesLoginModule as the first login module in the chain. The usersProperties and rolesProperties parameters can be directed to dummy files.


<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
<module-option name="unauthenticatedIdentity">nobody</module-option>
<module-option name="usersProperties">props/users.properties</module-option>
<module-option name="rolesProperties">props/roles.properties</module-option>
</login-module>       

JBossJCA uses a ManagedConnectionPool to perform the pooling. The ManagedConnectionPool is made up of subpools depending upon the strategy chosen and other pooling parameters.

xml

mbean

Internal Name

Description

ByNothing

OnePool

A single pool of equivalent connections

<application-managed-security/>

ByApplication

PoolByCRI

Use the connection properties from allocateConnection()

<security-domain/>

ByContainer

PoolBySubject

A pool per Subject, e.g. preconfigured or EJB/Web login subjects

<security-domain-and-applicaton/>

ByContainerAndApplicaton

PoolBySubjectAndCri

A per Subject and connection property combination

Note

The xml names imply this is just about security. This is misleading.

For <security-domain-and-application/> the Subject always overrides any user/password from createConnection(user, password) in the CRI:

(
ConnectionRequestInfo
) 

This chapter discusses the JBoss server implementation of the JavaEE Connector Architecture (JCA). JCA is a resource manager integration API whose goal is to standardize access to non-relational resources in the same way the JDBC API standardized access to relational data. The purpose of this chapter is to introduce the utility of the JCA APIs and then describe the architecture of JCA in JBoss

The JBoss JCA framework provides the application server architecture extension required for the use of JCA resource adaptors. This is primarily a connection pooling and management extension along with a number of MBeans for loading resource adaptors into the JBoss server.

There are three coupled MBeans that make up a RAR deployment. These are the org.jboss.resource.deployment.RARDeployment, org.jboss.resource.connectionmanager.RARDeployment, and org.jboss.resource.connectionmanager.BaseConnectionManager2. The org.jboss.resource.deployment.RARDeployment is simply an encapsulation of the metadata of a RAR META-INF/ra.xml descriptor. It exposes this information as a DynamicMBean simply to make it available to the org.jboss.resource.connectionmanager.RARDeployment MBean.

The RARDeployer service handles the deployment of archives files containing resource adaptors (RARs). It creates the org.jboss.resource.deployment.RARDeployment MBeans when a RAR file is deployed. Deploying the RAR file is the first step in making the resource adaptor available to application components. For each deployed RAR, one or more connection factories must be configured and bound into JNDI. This task performed using a JBoss service descriptor that sets up a org.jboss.resource.connectionmanager.BaseConnectionManager2 MBean implementation with a org.jboss.resource.connectionmgr.RARDeployment dependent.

The org.jboss.resource.connectionmanager.BaseConnectionManager2 MBean is a base class for the various types of connection managers required by the JCA spec. Subclasses include NoTxConnectionManager, LocalTxConnectionManager and XATxConnectionManager. These correspond to resource adaptors that support no transactions, local transaction and XA transaction respectively. You choose which subclass to use based on the type of transaction semantics you want, provided the JCA resource adaptor supports the corresponding transaction capability.

The common attributes supported by the BaseConnectionManager2 MBean are:

The org.jboss.resource.connectionmanager.RARDeployment MBean manages configuration and instantiation ManagedConnectionFactory instance. It does this using the resource adaptor metadata settings from the RAR META-INF/ra.xml descriptor along with the RARDeployment attributes. The configurable attributes are:

The org.jboss.resource.connectionmanager.JBossManagedConnectionPool MBean is a connection pooling MBean. It is typically used as the embedded MBean value of the BaseConnectionManager2ManagedConnectionPool attribute. When you setup a connection manager MBean you typically embed the pool configuration in the connection manager descriptor. The configurable attributes of the JBossManagedConnectionPool are:

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 4.1, “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 4.1, “The nontransactional file system resource adaptor deployment descriptor.”.

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

<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://java.sun.com/xml/ns/connector
    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>

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 4.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 JavaEE 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.


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 4.2, “A sequence diagram illustrating the key interactions between the JBoss JCA 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.


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:

  • 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.

  • 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.

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

  • 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.

  • 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.

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

  • 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.

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

  • 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 JBoss JCA 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.