Introduction To The J2EE Connector Architecture
Introduction To The J2EE Connector Architecture
IBM e-business Architect Willy Farrell provides a hands-on, step-by-step introduction to the
J2EE Connector Architecture, the most relevant components beneath that architecture, and the
functionality of each of those components.
Getting started
What is this tutorial about?
This tutorial provides an overview of the Java™ 2 Enterprise Edition (J2EE) Connector
Architecture (JCA). The tutorial starts with a high-level look at JCA, encompassing its place in
the J2EE architecture, how it works to integrate enterprise-level systems, and the base elements
of the architecture. In the sections that follow, you'll explore each of these elements in more
detail, with step-by-step descriptions and examples. The course closes with a look at a sample
application that will help you see how all the parts of a JCA-compliant and enabled system work
together.
Introduction
Integration complexity
As you develop Web-based applications, you probably find that you need to integrate those
applications with the resources and data available in at least one enterprise information system
(EIS), such as an enterprise resource planning (ERP) system, a supply chain management
(SCM) system, or a transaction processing monitor (TPM). Such integration is the essence of e-
business strategy: we leverage and transform existing infrastructure, combining it with Web and
other open technologies to support new business processes, such as business-to-business (B2B)
transactions.
Prior to the advent of the J2EE Connector Architecture, integrating a J2EE application and an
EIS was complex and problematic, because no standard for such integration existed. Each EIS
vendor supplied its own solution to the problem. An EIS vendor usually didn't support all J2EE
application servers. All of this made it difficult to write truly portable applications that integrated with
enterprise information systems; a custom effort was required to integrate each application server-
EIS combination.
The figure below illustrates the J2EE application and EIS integration complexity.
The figure below shows how JCA can simplify connecting several application servers to a single
EIS, or a single application server to several EIS.
Elements of JCA
JCA is composed of three primary elements:
• System contracts
• Client API
• Resource adapter module
Each of these elements plays a specific role in JCA. We'll take a high-level look at each element
separately, then move on to the more complex discussion in the next section.
System contracts
System contracts define the connection between the application server and the EIS. The EIS side
of the system contract is implemented by a resource adapter -- a system-level software driver
specific to the EIS. The application server and the resource adapter collaborate by means of the
system contract to provide secure, robust, scalable access to the EIS.
• The connection management contract enables physical connections to the EIS and provides a
mechanism for the application server to pool those connections.
• The transaction management contract supports access to an EIS in a transactional context.
Transactions can be managed by the application server, providing transactions that
incorporate other resources besides the EIS, or they can be internal to the EIS resource
manager, in which case no transaction manager is required.
How system contracts are implemented on each side (application server and resource adapter) is
not specified by JCA; they can be implemented as each vendor sees fit.
Client API
The second element of JCA is the client API. The API can be specific to the resource adapter or
it can be the standard Common Client Interface (CCI) as defined by JCA. The CCI is meant to be
used by vendors to provide integration tools and frameworks, making it easier for developers to
access enterprise systems. It is recommended (but not mandated) that the resource adapter make
use of the CCI.
• The Java classes and interfaces that implement the resource adapter
• Any utility Java classes required by the resource adapter
• Any EIS-specific platform-dependent native libraries
• The deployment descriptor
Application servers make use of the deployment descriptor supplied with a resource adapter to
configure it to a specific operational environment.
JCA's infrastructure
JCA overview
With a basic understanding of JCA under your belt, you're ready to begin thinking more about
the elements working beneath the architecture. In this section you'll learn about the classes,
interfaces, and libraries that work together to create and manage connections, fulfill complex
transactions, and maintain security for JCA-compliant and -enabled systems.
javax.resource.cci.Connection) or they can be specific to the resource adapter. The classes that
implement these interfaces are also provided with the resource adapter.
The connection factory is obtained through the Java Naming and Directory Interface (JNDI) so
that the application need have no knowledge of the underlying implementation class. Once the
connection factory is retrieved, a connection is obtained from the connection factory through
the getConnection() method. At least one getConnection() method must be provided by the
connection factory, though more may be provided. It is important to note that a Connection is
an application-level handle to an underlying physical connection to the EIS, represented by a
ManagedConnection, which we'll discuss later.
Once the application component is finished with the connection, it calls the close() method on
the connection. A resource adapter is required to provide a method on the connection to close
the connection. This method must delegate the close to the ManagedConnection that created the
connection handle. Closing a connection handle should not close the physical connection to the
EIS.
Connection management
The getConnection() method in the connection factory does not actually create a connection;
it calls the allocateConnection() method on its associated ConnectionManager. The
ConnectionManager interface is implemented by the application server. It is associated with
a connection factory in an implementation-specific manner when the connection factory is
instantiated. The call to the ConnectionManager allows the application server to "hook in" to
the resource adapter functionality to provide pooling, transaction, and security services. A
ConnectionRequestInfo object may be passed to allocateConnection() to pass connection
request-specific information.
Connection pooling
To support connection pooling, the resource adapter provides a class that implements the
ManagedConnectionFactory interface. The ManagedConnectionFactory class acts as a factory for
both connection factory instances and ManagedConnection instances.
When the application server needs to create a connection factory, it calls the
createConnectionFactory() method, passing in an instance of ConnectionManager; this is the
instance that is called when the application component calls getConnection() on the connection
factory, as discussed previously.
match, the server passes in a set of ManagedConnections that could possibly meet the criteria of
the requested connection, along with information about the desired connection type. Internally, the
matchManagedConnection() method compares this information with the candidate set to determine
if a match can be made. If so, it returns the matching ManagedConnection; if not, it returns null.
Transaction management
Two types of transaction management are available in JCA. The first type involves a transaction
manager coordinating the activity of multiple resource managers across a single transaction. The
second type involves a transaction with only a single resource manager, called a local transaction.
A resource adapter can also indicate, through its deployment descriptor, that it does not support
transactions.
Multiple resource managers participating in the same transaction are supported by the Java
Transaction API (JTA) XAResource interface. This interface allows a transaction manager to
manage transactions among multiple resources that support the interface. The ManagedConnection
interface contains a method, getXAResource(), which returns an XAResource object. The
application server's transaction manager uses this object to manage the transaction. For more
information on XAResource, see the JTA specification.
Security
JCA's security contract uses the Java Authentication and Authorization Service (JAAS)
Subject class to provide security information. When a new ManagedConnection is created,
The resource adapter's deployment descriptor lists the type of security supported, the
authentication mechanism used, the interface of the credentials supported, and whether re-
authentication is supported. The getConnection() method of ManagedConnection takes a Subject
as a parameter to support re-authentication. The following figure shows the security management
process.
Because only a couple of methods on the resource adapter are concerned with security, security
management seems somewhat simple. Like transaction management, however, the complexity
is in the collaboration between the application server and the resource adapter. A comprehensive
understanding of JAAS and the JCA security contract is required to ensure effective security. See
Related topics for more information on JAAS.
ManagedConnectionMetaData interface
While not specifically mentioned in JCA's three system contracts, the ManagedConnectionMetaData
interface is an important component of JCA. It provides methods to retrieve information about the
ManagedConnection and the connected EIS. This information includes:
• Connection-related interfaces
• Interaction-related interfaces
• Data representation-related interfaces
• Metadata-related interfaces
• Exceptions and warnings
A resource adapter is not required to provide support for the CCI. In fact, the resource adapter
may define its own client API, different from the CCI.
Connection-related interfaces
The CCI uses its ConnectionFactory interface to get a connection handle to an EIS. The
ConnectionFactory provides two getConnection() methods: one with no parameters and one
that takes a ConnectionSpec instance as a parameter. The second getConnection() is used when
connection request-specific information must be provided with the connection request.
The ConnectionFactory also provides methods to return metadata information about the resource
adapter (getResourceAdapterMetaData()) and to return a record factory (getRecordFactory()).
ConnectionSpec is an empty interface that may be extended to add whatever properties are
desired. Two standard properties, UserName and Password, are defined by JCA, but additional
properties (or no properties) may be supported. The resource adapter should map the properties
of ConnectionSpec to those of ConnectionRequestInfo when calling allocateConnection() on the
ConnectionManager.
Connection methods
The Connection interface is an application-level connection handle that is used to access an EIS. It
provides the following methods to manage connections between the application and the EIS:
• The close() method allows an application to close the connection handle, as required by the
connection-management contract.
• The getLocalTransaction() method allows an application component to use local
transactions.
• The createInteraction() method returns an Interaction object, which is used for accessing
EIS functions.
• The getResultSetInfo() method returns information about the result set functionality
supported by the EIS.
• The getMetaData() function returns metadata about the connection.
Interaction-related interfaces
An Interaction instance allows an application component to execute EIS functions. It has two
execute() methods: one that takes an InteractionSpec and an input Record and returns an output
Record, and one that takes an InteractionSpec, an input Record, and an output Record. This
method executes the appropriate EIS function, as defined in InteractionSpec, and updates the
output Record.
The Interaction must maintain its association with the Connection that created it, and the
getConnection() must return that Connection.
The close() method on an Interaction should release all resources maintained for the
Interaction, but should not close the Connection.
Three additional interfaces that extend Record are also provided. The MappedRecord interface
provides access to the record elements in a key-value map collection. The IndexedRecord interface
provides access to the record elements as an ordered collection. The ResultSet interface is based
on the JDBC ResultSet and provides similar functionality for accessing EIS data.
Metadata-related interfaces
The ConnectionMetaData interface provides information about the EIS name, the EIS version, and
the user name, similar to the ManagedConnectionMetaData interface.
ResourceWarning provides information about warnings that have been returned by an EIS as the
result of an Interaction. ResourceWarnings form a chain; a call to getWarnings() on Interaction
retrieves the first warning, and the rest of the chain is accessed through that warning.
As you can probably guess from its name, this resource adapter implements the ubiquitous
"Hello World" functionality. As such, it doesn't actually connect to an enterprise system, and its
functionality is limited to returning just the one String with the much-loved message. Although the
resource adapter does not implement the transaction or security contracts, it does implement the
CCI; it uses an Interaction, an InteractionSpec, a RecordFactory, and IndexedRecords.
You'll find the most important and interesting parts of the sample resource adapter extracted and
explained in the discussion that follows. In addition to classes and interfaces, we'll discuss the
source code for the deployment descriptor. From this simple implementation, you will be able to
get some feel for the classes you will need to write and the relationships between them. In addition
to studying the following two sections, you should spend some time reviewing the complete source
code, which you will find in Related topics.
HelloWorldConnectionFactoryImpl class
The HelloWorldConnectionFactoryImpl class implements the CCI ConnectionFactory interface
and provides the connection factory used by application components to create connections to the
EIS. Following is the code to create a HelloWorldConnectionFactoryImpl instance, as well as the
client methods that return connections, the record factory, and metadata.
...
public HelloWorldConnectionFactoryImpl(
ManagedConnectionFactory mcf,
ConnectionManager cm) {
super();
this.mcf = mcf;
this.cm = cm;
}
...
Getting a connection
Neither ConnectionRequestInfo nor ConnectionSpec are supported by the
HelloWorldConnectionFactoryImpl class, so both getConnection() methods do the same
thing: they call the allocateConnection() method of the ConnectionManager, passing in the
ManagedConnectionFactory and null for the ConnectionRequestInfo, as shown below:
...
public Connection getConnection() throws ResourceException {
return getConnection();
}
...
HelloWorldConnectionImpl class
The HelloWorldConnectionImpl class implements the CCI Connection interface, and provides the
connection handle for application components to access the EIS. Following are the methods to
create, invalidate, and close a connection, the methods to provide clients with an Interaction and
with metadata, and the code for signalling that the class does not support local transactions and
result sets.
Creating a connection
super();
this.mc = mc;
valid = true;
}
...
Invalidating a connection
The invalidate() method sets the ManagedConnection reference to null and sets the flag
indicating that the connection is no longer valid.
...
void invalidate() {
mc = null;
valid = false;
}
...
Closing a connection
The close() method delegates its invocation to the ManagedConnection, as required.
...
public void close() throws ResourceException {
if (valid) {
((HelloWorldManagedConnectionImpl) mc).close();
}
}
...
...
public Interaction createInteraction() throws ResourceException {
if (valid) {
return new HelloWorldInteractionImpl(this);
} else {
throw new ResourceException(CLOSED_ERROR);
}
}
if (valid) {
return new HelloWorldConnectionMetaDataImpl();
} else {
throw new ResourceException(CLOSED_ERROR);
}
}
...
Throwing a NotSupportedException
Because neither local transactions nor results sets are supported by this resource adapter,
getLocalTransaction() and getResultSetInfo() throw NotSupportedException.
...
public LocalTransaction getLocalTransaction() throws ResourceException {
HelloWorldManagedConnectionFactoryImpl class
...
public Object createConnectionFactory(ConnectionManager cm)
throws ResourceException {
...
public ManagedConnection matchManagedConnections(
Set connectionSet,
Subject subject,
ConnectionRequestInfo cxRequestInfo)
throws ResourceException {
return match;
}
...
HelloWorldManagedConnectionImpl class
Creating a connection
The getConnection() method first invalidates an existing connection handle, if one exists, then
creates a new connection handle, storing it in an instance variable. It then returns a reference to
that instance variable. This maintains a one-to-one relationship between the connection handle
and the ManagedConnection. A resource adapter may have multiple connection handles associated
with a ManagedConnection, but is not required to do so.
...
public Object getConnection(
Subject subject,
ConnectionRequestInfo cxRequestInfo)
throws ResourceException {
if (connection != null) {
connection.invalidate();
}
connection = new HelloWorldConnectionImpl(this);
return connection;
}
...
Closing a connection
The close() method notifies its ConnectionEventListeners that the close has occurred, then
invalidates the connection handle.
...
public void close() {
connection.invalidate();
}
connection.invalidate();
connection = null;
listeners = null;
}
...
Throwing a NotSupportedException
Because transactions are not supported by this resource adapter, the getXAResource() and
getLocalTransaction() methods both throw NotSupportedException.
...
public XAResource getXAResource() throws ResourceException {
HelloWorldInteractionImpl class
The HelloWorldInteractionImpl class implements the CCI Interaction interface. In this section,
you'll see how some of the more important elements of this class work together to create, execute,
and close an Interaction.
Creating an Interaction
Because JCA requires that an Interaction maintain its association with the connection handle
used to create it, the constructor requires that a Connection be passed in. A flag is set during
instantiation to indicate that this is a valid Interaction, that is, not closed. In other methods, where
appropriate, this flag is checked to determine if the requested action can be carried out.
...
public HelloWorldInteractionImpl(Connection connection) {
super();
this.connection = connection;
valid = true;
}
...
Executing an Interaction
The HelloWorldInteractionImpl class only supports the execute() variant that takes
an InteractionSpec, an input record, and an output record (the other execute() throws
NotSupportedException). The method ensures that:
if (valid) {
if (((HelloWorldInteractionSpecImpl) ispec)
.getFunctionName()
.equals(HelloWorldInteractionSpec.SAY_HELLO_FUNCTION)) {
if (input.getRecordName().equals(HelloWorldIndexedRecord.INPUT)) {
if
(output.getRecordName().equals(HelloWorldIndexedRecord.OUTPUT)) {
((HelloWorldIndexedRecord) output).clear();
((HelloWorldIndexedRecord) output).add(
OUTPUT_RECORD_FIELD_01);
} else {
throw new ResourceException(INVALID_OUTPUT_ERROR);
}
} else {
throw new ResourceException(INVALID_INPUT_ERROR);
}
} else {
throw new ResourceException(INVALID_FUNCTION_ERROR);
}
} else {
throw new ResourceException(CLOSED_ERROR);
}
return true;
}
...
Closing an Interaction
The close() method clears the connection handle and marks the Interaction as invalid.
...
public void close() throws ResourceException {
connection = null;
valid = false;
}
...
HelloWorldInteractionSpec class
To hide as much implementation detail as possible from application components using this
resource adapter, the HelloWorldInteractionSpec interface extends InteractionSpec. The
InteractionSpec interface lets us provide all the information application components must have. In
the next section, we'll look at the implementation class for this interface.
...
public interface HelloWorldInteractionSpec extends InteractionSpec {
HelloWorldInteractionSpecImpl class
...
public String getFunctionName() {
return functionName;
}
HelloWorldIndexedRecord class
HelloWorldIndexedRecordImpl class
...
public class HelloWorldIndexedRecordImpl implements HelloWorldIndexedRecord {
HelloWorldRecordFactoryImpl class
The createIndexedRecord() method ensures that the requested record name is valid, then creates
the record and returns it. If the record name is not valid, an exception is thrown.
...
public IndexedRecord createIndexedRecord(String recordName)
throws ResourceException {
if ((recordName.equals(HelloWorldIndexedRecord.INPUT))
|| (recordName.equals(HelloWorldIndexedRecord.OUTPUT))) {
record = new HelloWorldIndexedRecordImpl();
record.setRecordName(recordName);
}
if (record == null) {
throw new ResourceException(INVALID_RECORD_NAME);
} else {
return record;
}
}
...
It also indicates that neither transactions nor re-authentication are supported. If the transaction and
security contracts are supported, the deployment descriptor will contain additional elements.
< !DOCTYPE connector PUBLIC '-//Sun Microsystems, Inc.//
DTD Connector 1.0//EN' 'http://java.sun.com/dtd/connector_1_0.dtd'>
<connector>
<display-name>Hello World Sample</display-name>
<vendor-name>Willy Farrell</vendor-name>
<spec-version>1.0</spec-version>
<eis-type>Hello World</eis-type>
<version>1.0</version>
<resourceadapter>
<managedconnectionfactory-class>
com.ibm.ssya.helloworldra.HelloWorldManagedConnectionFactoryImpl
</managedconnectionfactory-class>
<connectionfactory-interface>
javax.resource.cci.ConnectionFactory
</connectionfactory-interface>
<connectionfactory-impl-class>
com.ibm.ssya.helloworldra.HelloWorldConnectionFactoryImpl
</connectionfactory-impl-class>
<connection-interface>
javax.resource.cci.Connection
</connection-interface>
<connection-impl-class>
com.ibm.ssya.helloworldra.HelloWorldConnectionImpl
</connection-impl-class>
<transaction-support>
NoTransaction
</transaction-support>
<reauthentication-support>
false
</reauthentication-support>
</resourceadapter>
</connector>
Sample application
J2EE Web application
You should now have a fairly comprehensive understanding of how JCA's components work
together to create and manage complex interactions with an enterprise system. All that's left to
do is play with the code itself. You will find a sample application that uses the sample resource
adapter in the file helloworldra.ear. It is a J2EE Web application with an input HTML form (with
only a Submit button), a servlet controller, a JavaBeans component that invokes the resource
adapter, and a JavaServer Pages (JSP) component to display the results of the invocation.
We'll close this tutorial with a look at the bean that invokes the resource adapter, as well as
another class (provided separately from the .ear file) that helps deploy an InteractionSpec
instance into JNDI.
HelloWorldBean class
This HelloWorldBean class, through its execute() method, invokes the resource adapter, using
the CCI interface. First, the ConnectionFactory is retrieved from JNDI and is used to create a
RecordFactory. The RecordFactory is used to create an input record and an output record.
Next, an InteractionSpec is retrieved from JNDI. Then a Connection is created from the
ConnectionFactory and an Interaction is created from the Connection. The Interaction is used
to execute the function, and the results are stored in the bean's Message property.
You will observe that the two JNDI lookups are different. The lookup of the ConnectionFactory
is done using the java:comp/env context, while the lookup of the InteractionSpec is not. This is
because the environment that was used to develop and test the resource adapter and sample
application did not have a deployment tool to bind an InteractionSpec into JNDI; it only provided
for binding the ConnectionFactory, which could then be accessed using a resource reference in
the Web application.
...
public void execute() throws NamingException, ResourceException {
DeployISpec class
The DeployISpec class, which is provided in the helloworldradeploy.jar file, is used to deploy
the InteractionSpec object into JNDI if your deployment environment does not provide a tool to
accomplish that. It has a simple main() method that creates the InteractionSpec and binds it into
JNDI. This class should be run after the resource adapter is deployed and the connection factory
has been bound into JNDI.
...
public static void main(String[] args) throws NamingException {
After deploying the Web application, you should pull up a browser and load the URL http://
SERVER_NAME/hello. Once the page has loaded, click the Submit button and the results page with
the "Hello World!" message should appear.
The sample resource adapter and sample application were successfully deployed and tested on
IBM WebSphere Application Server Advanced Edition Version 4.03.
Wrapup
Summary
In this tutorial, you have been introduced to the J2EE Connector Architecture. We started with a
high-level view of JCA and its primary elements: system contracts, the client API, and the resource
adapter module. From there, we moved on to a more detailed discussion, encompassing the
interfaces, classes, and methods that work beneath JCA to create and manage connections to an
EIS. As part of this discussion, we looked at the source code for an actual JCA implementation.
Each of the most relevant components of the implementation was pulled out, and its various
functions explained in detail. We closed with an actual resource adapter implementation, which
you are free to continue exploring on your own.
This tutorial has provided you a hands-on, step-by-step introduction to the J2EE Connector
Architecture, the most relevant components beneath that architecture, and the functionality of each
of those components. You should now have a fairly good foundation for building your own JCA
resource adapter and connecting to an EIS.
Downloadable resources
Description Name Size
helloworldra.zip 38KB
Related topics
• The J2EE Connector Architecture specification is the definitive source for information about
JCA.
• The Java Transaction API specification and the Java Transaction Service specification help
you understand how to implement the JCA transaction management contract.
• Java theory and practice columnist Brian Goetz offers a three-part introduction to
the Java Transaction Service, starting with "Understanding JTS -- An introduction to
transactions" (developerWorks, March 2002).
• Because exception-handling is an important part of any component you build, you
may also want to check out Srikanth Shenoy's "Best practices in EJB exception
handling" (developerWorks, May 2002).
• The Java Authentication and Authorization Specification will help you understand how to
implement the JCA security contract.
• developerWorks two-part Java security tutorial serves as a more hands-on introduction to
the JAAS. Start with "Part 1: Crypto basics" (July 2002), then see "Part 2: Authentication and
authorization" (July 2002).
• Also see the developerWorks Java technology tutorials page for a complete listing of free
tutorials.
• You can download the most recent version of J2EE (including JCA) from Sun Microsystems.