The Java EE 6 Tutorial, Volume I

Part VIII JavaTM EE Supporting Technologies

Part Eight explores several technologies that support the Java EE platform.

Chapter 26 Introduction to JavaTM EE Supporting Technologies

The Java EE platform includes several technologies and APIs that extend its functionality. These technologies allow applications to access a wide range of services in a uniform manner.

This chapter introduces the following Java EE technologies:

These technologies are explained in greater in subsequent chapters: Chapter 27, Transactions and Chapter 28, Resource Connections.

The following topics are addressed here:

Transactions

A transaction is a series of actions in a Java EE application that must all complete successfully or else all the changes in each action are backed out. Transactions end in either a commit or a rollback.

The Java Transaction API (JTA) allows applications to access transactions in a manner that is independent of specific implementations. JTA specifies standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system: the transactional application, the Java EE server, and the manager that controls access to the shared resources affected by the transactions.

The JTA defines the UserTransaction interface that is used by applications to start, and commit or abort transactions. Application components get a UserTransaction object through a JNDI lookup using the name java:comp/UserTransaction or by requesting injection of a UserTransaction object. A number of interfaces defined by JTA are used by an application server to communicate with a transaction manager, and for a transaction manager to interact with a resource manager.

See the Chapter 27, Transactions chapter for a more detailed explanation. The JTA 1.1 specification is available at http://java.sun.com/javaee/technologies/jta/index.jsp.

Resources

A resource is a program object that provides connections to systems such as database servers and messaging systems.

The Java EE Connector Architecture and Resource Adapters

The Java EE Connector 1.6 architecture enables Java EE components to interact with enterprise information systems (EISs) and EISs to interact with Java EE components. EIS software includes various types of systems: enterprise resource planning (ERP), mainframe transaction processing, and nonrelational databases, among others. Connector architecture simplifies the integration of diverse EISs. Each EIS requires only one implementation of the Connector architecture. Because an implementation adheres to the Connector specification, it is portable across all compliant Java EE servers.

The specification defines the contracts for an application server as well as for resource adapters, which are system-level software drivers for specific EIS resources. These standard contracts provide pluggability between application servers and EISs. The Java EE Connector 1.6 specification defines new system contracts such as Generic Work Context and Security Inflow.

The Java EE Connector 1.6 specification is available at: http://jcp.org/en/jsr/detail?id=322

A resource adapter is a Java EE component that implements the Connector architecture for a specific EIS.

A resource adapter can choose to support the following levels of transactions:

See the Chapter 28, Resource Connections chapter for a more detailed explanation of resource adapters.

Java Message Service

Messaging is a method of communication between software components or applications. A messaging system is a peer-to-peer facility: A messaging client can send messages to, and receive messages from, any other client. Each client connects to a messaging agent that provides facilities for creating, sending, receiving, and reading messages.

The Java Message Service API is a Java API that allows applications to create, send, receive, and read messages. Designed by Sun and several partner companies, the JMS API defines a common set of interfaces and associated semantics that allow programs written in the Java programming language to communicate with other messaging implementations.

The JMS API minimizes the set of concepts a programmer must learn in order to use messaging products but provides enough features to support sophisticated messaging applications. It also strives to maximize the portability of JMS applications across JMS providers in the same messaging domain.

Sun GlassFishTM Enterprise Server v3 implements the Java Message Service (JMS) API by integrating the Sun GlassFish Message Queue software with the Enterprise Server software.

Java DataBase Connectivity (JDBCTM) Software

To store, organize, and retrieve data, most applications use relational databases. Java EE applications access relational databases through the JDBC API.

A JDBC resource (data source) provides applications with a means of connecting to a database. Typically, a JDBC resource is created for each database accessed by the applications deployed in a domain. Transactional access to JDBC resources is available from servlets, JSP pages, and enterprise beans. The connection pooling and distributed transaction features are intended for use by JDBC drivers to coordinate with an application server.

For more information, see DataSource Objects and Connection Pools.

Chapter 27 Transactions

A typical enterprise application accesses and stores information in one or more databases. Because this information is critical for business operations, it must be accurate, current, and reliable. Data integrity would be lost if multiple programs were allowed to update the same information simultaneously. It would also be lost if a system that failed while processing a business transaction were to leave the affected data only partially updated. By preventing both of these scenarios, software transactions ensure data integrity. Transactions control the concurrent access of data by multiple programs. In the event of a system failure, transactions make sure that after recovery the data will be in a consistent state.

The following topics are addressed here:

What Is a Transaction?

To emulate a business transaction, a program may need to perform several steps. A financial program, for example, might transfer funds from a checking account to a savings account using the steps listed in the following pseudocode:

begin transaction
	debit checking account
	credit savings account
	update history log
commit transaction

Either all three of these steps must complete, or none of them at all. Otherwise, data integrity is lost. Because the steps within a transaction are a unified whole, a transaction is often defined as an indivisible unit of work.

A transaction can end in two ways: with a commit or with a rollback. When a transaction commits, the data modifications made by its statements are saved. If a statement within a transaction fails, the transaction rolls back, undoing the effects of all statements in the transaction. In the pseudocode, for example, if a disk drive were to crash during the credit step, the transaction would roll back and undo the data modifications made by the debit statement. Although the transaction fails, data integrity would be intact because the accounts still balance.

In the preceding pseudocode, the begin and commit statements mark the boundaries of the transaction. When designing an enterprise bean, you determine how the boundaries are set by specifying either container-managed or bean-managed transactions.

Container-Managed Transactions

In an enterprise bean with container-managed transaction demarcation, the EJB container sets the boundaries of the transactions. You can use container-managed transactions with any type of enterprise bean: session, or message-driven. Container-managed transactions simplify development because the enterprise bean code does not explicitly mark the transaction’s boundaries. The code does not include statements that begin and end the transaction.

By default if no transaction demarcation is specified enterprise beans use container-managed transaction demarcation.

Typically, the container begins a transaction immediately before an enterprise bean method starts. It commits the transaction just before the method exits. Each method can be associated with a single transaction. Nested or multiple transactions are not allowed within a method.

Container-managed transactions do not require all methods to be associated with transactions. When developing a bean, you can specify which of the bean’s methods are associated with transactions by setting the transaction attributes.

Enterprise beans that use container-managed transaction demarcation must not use any transaction management methods that interfere with the container’s transaction demarcation boundaries. Examples of such methods are the commit, setAutoCommit, and rollback methods of java.sql.Connection or the commit and rollback methods of javax.jms.Session. If you require control over the transaction demarcation, you must use application-managed transaction demarcation.

Enterprise beans that use container-managed transaction demarcation also must not use the javax.transaction.UserTransaction interface.

Transaction Attributes

A transaction attribute controls the scope of a transaction. Figure 27–1 illustrates why controlling the scope is important. In the diagram, method-A begins a transaction and then invokes method-B of Bean-2. When method-B executes, does it run within the scope of the transaction started by method-A, or does it execute with a new transaction? The answer depends on the transaction attribute of method-B.

Figure 27–1 Transaction Scope

A diagram showing a transaction between two beans.

A transaction attribute can have one of the following values:

Required Attribute

If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.

The Required attribute is the implicit transaction attribute for all enterprise bean methods running with container-managed transaction demarcation. You typically do not set the Required attribute unless you need to override another transaction attribute. Because transaction attributes are declarative, you can easily change them later.

RequiresNew Attribute

    If the client is running within a transaction and invokes the enterprise bean’s method, the container takes the following steps:

  1. Suspends the client’s transaction

  2. Starts a new transaction

  3. Delegates the call to the method

  4. Resumes the client’s transaction after the method completes

If the client is not associated with a transaction, the container starts a new transaction before running the method.

You should use the RequiresNew attribute when you want to ensure that the method always runs within a new transaction.

Mandatory Attribute

If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container throws the TransactionRequiredException.

Use the Mandatory attribute if the enterprise bean’s method must use the transaction of the client.

NotSupported Attribute

If the client is running within a transaction and invokes the enterprise bean’s method, the container suspends the client’s transaction before invoking the method. After the method has completed, the container resumes the client’s transaction.

If the client is not associated with a transaction, the container does not start a new transaction before running the method.

Use the NotSupported attribute for methods that don’t need transactions. Because transactions involve overhead, this attribute may improve performance.

Supports Attribute

If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container does not start a new transaction before running the method.

Because the transactional behavior of the method may vary, you should use the Supports attribute with caution.

Never Attribute

If the client is running within a transaction and invokes the enterprise bean’s method, the container throws a RemoteException. If the client is not associated with a transaction, the container does not start a new transaction before running the method.

Summary of Transaction Attributes

Table 27–1 summarizes the effects of the transaction attributes. Both the T1 and the T2 transactions are controlled by the container. A T1 transaction is associated with the client that calls a method in the enterprise bean. In most cases, the client is another enterprise bean. A T2 transaction is started by the container just before the method executes.

In the last column of Table 27–1, the word None means that the business method does not execute within a transaction controlled by the container. However, the database calls in such a business method might be controlled by the transaction manager of the DBMS.

Table 27–1 Transaction Attributes and Scope

Transaction Attribute 

Client’s Transaction 

Business Method’s Transaction 

Required

None 

T2 

 

T1 

T1 

RequiresNew

None 

T2 

 

T1 

T2 

Mandatory

None 

error 

 

T1 

T1 

NotSupported

None 

None 

 

T1 

None 

Supports

None 

None 

 

T1 

T1 

Never

None 

None 

 

T1 

Error 

Setting Transaction Attributes

Transaction attributes are specified by decorating the enterprise bean class or method with a javax.ejb.TransactionAttribute annotation, and setting it to one of the javax.ejb.TransactionAttributeType constants.

If you decorate the enterprise bean class with @TransactionAttribute, the specified TransactionAttributeType is applied to all the business methods in the class. Decoration a business method with @TransactionAttribute applies the TransactionAttributeType only to that method. If a @TransactionAttributeannotation decorates both the class and the method, the method TransactionAttributeType overrides the class TransactionAttributeType.

The TransactionAttributeType constants encapsulate the transaction attributes described earlier in this section.

The following code snippet demonstrates how to use the @TransactionAttribute annotation:

@TransactionAttribute(NOT_SUPPORTED)
@Stateful
public class TransactionBean implements Transaction {
...
    @TransactionAttribute(REQUIRES_NEW)
    public void firstMethod() {...}

    @TransactionAttribute(REQUIRED)
    public void secondMethod() {...}

    public void thirdMethod() {...}

    public void fourthMethod() {...}
}

In this example, the TransactionBean class’s transaction attribute has been set to NotSupported. firstMethod has been set to RequiresNew, and secondMethod has been set to Required. Because a @TransactionAttribute set on a method overrides the class @TransactionAttribute, calls to firstMethod will create a new transaction, and calls to secondMethod will either run in the current transaction, or start a new transaction. Calls to thirdMethod or fourthMethod do not take place within a transaction.

Rolling Back a Container-Managed Transaction

There are two ways to roll back a container-managed transaction. First, if a system exception is thrown, the container will automatically roll back the transaction. Second, by invoking the setRollbackOnly method of the EJBContext interface, the bean method instructs the container to roll back the transaction. If the bean throws an application exception, the rollback is not automatic but can be initiated by a call to setRollbackOnly.

Synchronizing a Session Bean’s Instance Variables

The SessionSynchronization interface, which is optional, allows stateful session bean instances to receive transaction synchronization notifications. For example, you could synchronize the instance variables of an enterprise bean with their corresponding values in the database. The container invokes the SessionSynchronization methods (afterBegin, beforeCompletion, and afterCompletion) at each of the main stages of a transaction.

The afterBegin method informs the instance that a new transaction has begun. The container invokes afterBegin immediately before it invokes the business method.

The container invokes the beforeCompletion method after the business method has finished, but just before the transaction commits. The beforeCompletion method is the last opportunity for the session bean to roll back the transaction (by calling setRollbackOnly).

The afterCompletion method indicates that the transaction has completed. It has a single boolean parameter whose value is true if the transaction was committed and false if it was rolled back.

Methods Not Allowed in Container-Managed Transactions

You should not invoke any method that might interfere with the transaction boundaries set by the container. The list of prohibited methods follows:

You can, however, use these methods to set boundaries in application-managed transactions.

Bean-Managed Transactions

In bean-managed transaction demarcation, the code in the session or message-driven bean explicitly marks the boundaries of the transaction. Although beans with container-managed transactions require less coding, they have one limitation: When a method is executing, it can be associated with either a single transaction or no transaction at all. If this limitation will make coding your bean difficult, you should consider using bean-managed transactions.

The following pseudocode illustrates the kind of fine-grained control you can obtain with application-managed transactions. By checking various conditions, the pseudocode decides whether to start or stop different transactions within the business method.

begin transaction
...
	update table-a
...
	if (condition-x)
   commit transaction
	else if (condition-y)
   update table-b
   commit transaction
	else
   rollback transaction
   begin transaction
   update table-c
   commit transaction

When coding a application-managed transaction for session or message-driven beans, you must decide whether to use JavaTM DataBase Connectivity (JDBCTM) or JTA transactions. The sections that follow discuss both types of transactions.

JTA Transactions

JTA is the abbreviation for the Java Transaction API. This API allows you to demarcate transactions in a manner that is independent of the transaction manager implementation. Sun GlassFishTM Enterprise Server v3 implements the transaction manager with the Java Transaction Service (JTS). But your code doesn’t call the JTS methods directly. Instead, it invokes the JTA methods, which then call the lower-level JTS routines.

A JTA transaction is controlled by the Java EE transaction manager. You may want to use a JTA transaction because it can span updates to multiple databases from different vendors. A particular DBMS’s transaction manager may not work with heterogeneous databases. However, the Java EE transaction manager does have one limitation: it does not support nested transactions. In other words, it cannot start a transaction for an instance until the preceding transaction has ended.

To demarcate a JTA transaction, you invoke the begin, commit, and rollback methods of the javax.transaction.UserTransaction interface.

Returning without Committing

In a stateless session bean with bean-managed transactions, a business method must commit or roll back a transaction before returning. However, a stateful session bean does not have this restriction.

In a stateful session bean with a JTA transaction, the association between the bean instance and the transaction is retained across multiple client calls. Even if each business method called by the client opens and closes the database connection, the association is retained until the instance completes the transaction.

In a stateful session bean with a JDBC transaction, the JDBC connection retains the association between the bean instance and the transaction across multiple calls. If the connection is closed, the association is not retained.

Methods Not Allowed in Bean-Managed Transactions

Do not invoke the getRollbackOnly and setRollbackOnly methods of the EJBContext interface in bean-managed transactions. These methods should be used only in container-managed transactions. For bean-managed transactions, invoke the getStatus and rollback methods of the UserTransaction interface.

Transaction Timeouts

For container-managed transactions, you can use the Admin Console to configure the transaction timeout interval. SeeStarting the Administration Console.

  1. In the Admin Console, expand the Configuration node and select Transaction Service.

  2. On the Transaction Service page, set the value of the Transaction Timeout field to the value of your choice (for example, 5).

    With this setting, if the transaction has not completed within 5 seconds, the EJB container rolls it back.

    The default value is 0, meaning that the transaction will not time out.

  3. Click Save.

For enterprise beans with bean-managed JTA transactions, you invoke the setTransactionTimeout method of the UserTransaction interface.

Updating Multiple Databases

The Java EE transaction manager controls all enterprise bean transactions except for bean-managed JDBC transactions. The Java EE transaction manager allows an enterprise bean to update multiple databases within a transaction. The figures that follow show two scenarios for updating multiple databases in a single transaction.

In Figure 27–2, the client invokes a business method in Bean-A. The business method begins a transaction, updates Database X, updates Database Y, and invokes a business method in Bean-B. The second business method updates Database Z and returns control to the business method in Bean-A, which commits the transaction. All three database updates occur in the same transaction.

Figure 27–2 Updating Multiple Databases

A diagram showing Bean-A updating databases X and Y,
and Bean-B updating database Z.

In Figure 27–3, the client calls a business method in Bean-A, which begins a transaction and updates Database X. Then Bean-A invokes a method in Bean-B, which resides in a remote Java EE server. The method in Bean-B updates Database Y. The transaction managers of the Java EE servers ensure that both databases are updated in the same transaction.

Figure 27–3 Updating Multiple Databases across Java EE Servers

A diagram showing Bean-A on one Java EE server updating
database X, and Bean-B on another Java EE server updating database Y.

Transactions in Web Components

You can demarcate a transaction in a web component by using either the java.sql.Connection or javax.transaction.UserTransaction interface. These are the same interfaces that a session bean with bean-managed transactions can use. Transactions demarcated with the UserTransaction interface are discussed in the section JTA Transactions.

Chapter 28 Resource Connections

JavaTM EE components can access a wide variety of resources, including databases, mail sessions, Java Message Service objects, and URLs. The Java EE 6 platform provides mechanisms that allow you to access all these resources in a similar manner. This chapter describes how to get connections to several types of resources.

The following topics are addressed here:

Resources and JNDI Naming

In a distributed application, components need to access other components and resources such as databases. For example, a servlet might invoke remote methods on an enterprise bean that retrieves information from a database. In the Java EE platform, the Java Naming and Directory InterfaceTM (JNDI) naming service enables components to locate other components and resources.

A resource is a program object that provides connections to systems, such as database servers and messaging systems. (A Java DataBase Connectivity (JDBCTM) resource is sometimes referred to as a data source.) Each resource object is identified by a unique, people-friendly name, called the JNDI name.

For example, the JNDI name of the JDBC resource for the Java DB database that is shipped with Sun GlassFishTM Enterprise Server v3 (Enterprise Server) is jdbc/__default.

An administrator creates resources in a JNDI namespace. In the Enterprise Server, you can use either the Administration Console or the asadmin command to create resources. Applications then use annotations to inject the resources. If an application uses resource injection, the Enterprise Server invokes the JNDI API, and the application is not required to do so. However, it is also possible for an application to locate resources by making direct calls to the JNDI API.

A resource object and its JNDI name are bound together by the naming and directory service. To create a new resource, a new name-object binding is entered into the JNDI namespace. You inject resources by using the @Resource annotation in an application.

You can use a deployment descriptor to override the resource mapping that you specify in an annotation. Using a deployment descriptor allows you to change an application by repackaging it, rather than by both recompiling the source files and repackaging. However, for most applications, a deployment descriptor is not necessary.

DataSource Objects and Connection Pools

To store, organize, and retrieve data, most applications use a relational database. Java EE 6 components may access relational databases through the JDBC API. For information on this API, see http://java.sun.com/javase/technologies/database/.

In the JDBC API, databases are accessed by using DataSource objects. A DataSource has a set of properties that identify and describe the real world data source that it represents. These properties include information such as the location of the database server, the name of the database, the network protocol to use to communicate with the server, and so on. In the Sun GlassFish Enterprise Server, a data source is called a JDBC resource.

Applications access a data source using a connection, and a DataSource object can be thought of as a factory for connections to the particular data source that the DataSource instance represents. In a basic DataSource implementation, a call to the getConnection method returns a connection object that is a physical connection to the data source.

If a DataSource object is registered with a JNDI naming service, an application can use the JNDI API to access that DataSource object, which can then be used to connect to the data source it represents.

DataSource objects that implement connection pooling also produce a connection to the particular data source that the DataSource class represents. The connection object that the getConnection method returns is a handle to a PooledConnection object rather than being a physical connection. An application uses the connection object in the same way that it uses a connection. Connection pooling has no effect on application code except that a pooled connection, like all connections, should always be explicitly closed. When an application closes a connection that is pooled, the connection is returned to a pool of reusable connections. The next time getConnection is called, a handle to one of these pooled connections will be returned if one is available. Because connection pooling avoids creating a new physical connection every time one is requested, applications can run significantly faster.

A JDBC connection pool is a group of reusable connections for a particular database. Because creating each new physical connection is time consuming, the server maintains a pool of available connections to increase performance. When an application requests a connection, it obtains one from the pool. When an application closes a connection, the connection is returned to the pool.

Applications that use the Persistence API specify the DataSource object they are using in the jta-data-source element of the persistence.xml file.

<jta-data-source>jdbc/MyOrderDB</jta-data-source>

This is typically the only reference to a JDBC object for a persistence unit. The application code does not refer to any JDBC objects.

Resource Injection

The javax.annotation.Resource annotation is used to declare a reference to a resource. @Resource can decorate a class, a field, or a method. The container will inject the resource referred to by @Resource into the component either at runtime or when the component is initialized, depending on whether field/method injection or class injection is used. With field and method-based injection, the container will inject the resource when the application is initialized. For class-based injection, the resource is looked up by the application at runtime.

@Resource has the following elements:

The name element is the JNDI name of the resource, and is optional for field- and method-based injection. For field-based injection, the default name is the field name qualified by the class name. For method-based injection, the default name is the JavaBeansTM property name based on the method qualified by the class name. The name element must be specified for class-based injection.

The type of resource is determined by one of the following:

For class-based injection, the type element is required.

The authenticationType element is used only for connection factory resources, such as the resources of a connector (also called the resource adapter or data source). This element can be set to one of the javax.annotation.Resource.AuthenticationType enumerated type values: CONTAINER, the default, and APPLICATION.

The shareable element is used only for Object Resource Broker (ORB) instance resources or connection factory resource. It indicates whether the resource can be shared between this component and other components, and may be set to true, the default, or false.

The mappedName element is a non-portable, implementation-specific name to which the resource should be mapped. Because the name element, when specified or defaulted, is local only to the application, many Java EE servers provide a way of referring to resources across the application server. This is done by setting the mappedName element. Use of the mappedName element is non-portable across Java EE server implementations.

The description element is the description of the resource, typically in the default language of the system on which the application is deployed. It is used to help identify resources, and to help application developers choose the correct resource.

Field-Based Injection

To use field-based resource injection, declare a field and decorate it with the @Resource annotation. The container will infer the name and type of the resource if the name and type elements are not specified. If you do specify the type element, it must match the field’s type declaration.

package com.example;

public class SomeClass {
    @Resource
    private javax.sql.DataSource myDB;
...
}

In the code above, the container infers the name of the resource based on the class name and the field name: com.example.SomeClass/myDB. The inferred type is javax.sql.DataSource.class.

package com.example;

public class SomeClass {
    @Resource(name="customerDB")
    private javax.sql.DataSource myDB;
...
}

In the code above, the JNDI name is customerDB, and the inferred type is javax.sql.DataSource.class.

Method-Based Injection

To use method-based injection, declare a setter method and decorate it with the @Resource annotation. The container will infer the name and type of the resource if the name and type elements are not specified. The setter method must follow the JavaBeans conventions for property names: the method name must begin with set, have a void return type, and only one parameter. If you do specify the type element, it must match the field’s type declaration.

package com.example;

public class SomeClass {

    private javax.sql.DataSource myDB;
...
    @Resource
    private void setMyDB(javax.sql.DataSource ds) {
        myDB = ds;
    }
...
}

In the code above, the container infers the name of the resource based on the class name and the field name: com.example.SomeClass/myDB. The inferred type is javax.sql.DataSource.class.

package com.example;

public class SomeClass {

    private javax.sql.DataSource myDB;
...
    @Resource(name="customerDB")
    private void setMyDB(javax.sql.DataSource ds) {
        myDB = ds;
    }
...
}

In the code above, the JNDI name is customerDB, and the inferred type is javax.sql.DataSource.class.

Class-Based Injection

To use class-based injection, decorate the class with a @Resource annotation, and set the required name and type elements.

@Resource(name="myMessageQueue",
                type="javax.jms.ConnectionFactory")
public class SomeMessageBean {
...
}

Declaring Multiple Resources

The @Resources annotation is used to group together multiple @Resource declarations for class-based injection.

@Resources({
    @Resource(name="myMessageQueue",
                    type="javax.jms.ConnectionFactory"),
    @Resource(name="myMailSession",
                    type="javax.mail.Session")
})
public class SomeMessageBean {
...
}

The code above shows the @Resources annotation containing two @Resource declarations. One is a Java Message Service (JMS) message queue, and the other is a JavaMailTM session.

Resource Adapters

A resource adapter is a Java EE component that implements the Java EE Connector Architecture for a specific Enterprise Information System (EIS). Examples of EISs include Enterprise Resource Planning (ERP), mainframe transaction processing (TP), and database systems. As illustrated in Figure 35-1, the resource adapter facilitates communication between a Java EE application and an EIS.

Resource Adapter Contracts

Stored in a Resource Adapter Archive (RAR) file, a resource adapter can be deployed on any Java EE server, much like a Java EE application. An RAR file may be contained in an Enterprise Archive (EAR) file, or it may exist as a separate file.

A resource adapter is analogous to a JDBC driver. Both provide a standard API through which an application can access a resource that is outside the Java EE server. For a resource adapter, the target system is an EIS; for a JDBC driver, it is a DBMS. Resource adapters and JDBC drivers are rarely created by application developers. In most cases, both types of software are built by vendors that sell products such as tools, servers, or integration software.

Resource Adapter Contracts

The resource adapter mediates communication between the Java EE server and the EIS by means of contracts. The application contract defines the API through which a Java EE component such as an enterprise bean accesses the EIS. This API is the only view that the component has of the EIS. The system contracts link the resource adapter to important services that are managed by the Java EE server. The resource adapter itself and its system contracts are transparent to the Java EE component.

Management Contracts

The Java EE Connector Architecture defines system contracts that enable resource adapter life cycle and thread management.

Life cycle Management

The Connector Architecture specifies a life cycle management contract that allows an application server to manage the life cycle of a resource adapter. This contract provides a mechanism for the application server to bootstrap a resource adapter instance during the deployment or application server startup. It also provides a means for the application server to notify the resource adapter instance when it is undeployed or when an orderly shutdown of the application server takes place.

Work Management Contract

The Connector Architecture work management contract ensures that resource adapters use threads in the proper, recommended manner. It also enables an application server to manage threads for resource adapters.

Resource adapters that improperly use threads can jeopardize the entire application server environment. For example, a resource adapter might create too many threads or it might not properly release threads it has created. Poor thread handling inhibits application server shutdown. It also impacts the application server's performance because creating and destroying threads are expensive operations.

The work management contract establishes a means for the application server to pool and reuse threads, similar to pooling and reusing connections. By adhering to this contract, the resource adapter does not have to manage threads itself. Instead, the resource adapter has the application server create and provide needed threads. When the resource adapter is finished with a given thread, it returns the thread to the application server. The application server manages the thread: It can return the thread to a pool and reuse it later, or it can destroy the thread. Handling threads in this manner results in increased application server performance and more efficient use of resources.

In addition to moving thread management to the application server, the Connector Architecture provides a flexible model for a resource adapter that uses threads:

With the latter two approaches, the submitting thread and the work thread may execute simultaneously or independently from each other. For these approaches, the contract specifies a listener mechanism to notify the resource adapter that the thread has completed its operation. The resource adapter can also specify the execution context for the thread, and the work management contract controls the context in which the thread executes.

Generic Work Context Contract

A generic work context contract enables a resource adapter to control the contexts in which the Work instances submitted by it are executed by the application server's WorkManager. A Generic Work context mechanism also enables an application server to support new message inflow and delivery schemes. It also provides a richer contextual Work execution environment to the resource adapter while still maintaining control over concurrent behavior in a managed environment.

The Generic Work Context contract standardizes the following contexts: Transaction Context and Security Context.

Transaction Context

The transaction context between the resource adapter and the application server leverages the Generic Work Context mechanism by describing a standard WorkContext, the TransactionContext. It represents the standard interface that a resource adapter can use to propagate transaction context information from the EIS to the application server.

Security Context

The security context between the resource adapter and the application server leverages the Generic Work Context mechanism by describing a standard WorkContext, the SecurityContext, that can be provided by the resource adapter while submitting a Work for execution.

The SecurityContext provides a portable mechanism for the resource adapter to pass security context information to the application server. This work context enables an EIS or resource adapter to flow-in security context information while submitting a Work to a WorkContext for execution.

Work Security Map

A work security map matches EIS identities to the application server domain's identities.

Hints Context

The propagation of Quality of Service hints to a WorkManager for the execution of a Work instance is standardized through the HintsContext class. It provides a mechanism for the resource adapter to pass quality-of-service metadata to the WorkManager during the submission of a Work instance. The application server can use the specified hints to control the execution of the Work instance.

Outbound Contracts

The Connector Architecture defines system-level contracts between an application server and an EIS that enable outbound connectivity to an EIS: connection management, transaction management, and security.

Connection Management Contract

The connection management contract supports connection pooling, a technique that enhances application performance and scalability. Connection pooling is transparent to the application, which simply obtains a connection to the EIS.

Transaction Management Contract

The Connector Architecture supports the concept of transactions - a number of operations that must be committed together or not at all for the data to remain consistent and to maintain data integrity.

A local transaction is limited in scope to a single EIS system, and the EIS resource manager itself manages such transaction. An XA transaction or global transaction can span multiple resource managers. This form of transaction requires transaction coordination by an external transaction manager, typically bundled with an application server. A transaction manager uses a two-phase commit protocol to manage a transaction that spans multiple resource managers or EISs. It uses one-phase commit optimization if only one resource manager is participating in an XA transaction.

The Connector Architecture defines a transaction management contract between an application server and a resource adapter . The transaction management contract extends the connection management contract and provides support for management of both local and XA transactions. These contracts enable an application server to provide the infrastructure and runtime environment for transaction management. Application components rely on this transaction infrastructure to support the component-level transaction model.

An application server is required to support all three levels of transactions:

Security Management Contract

The security management contract provides mechanisms for authentication, authorization, and secure communication between a Java EE server and an EIS to protect the information in the EIS.

Inbound Contracts

The Java EE Connector Architecture defines system contracts between a Java EE server and an EIS that enable inbound connectivity from the EIS: pluggability contracts for message providers and contracts for importing transactions.

Messaging Contracts

To enable external systems to connect to a Java EE application server, the Connector Architecture extends the capabilities of message-driven beans to handle messages from any message provider. That is, message-driven beans are no longer limited to handling JMS messages. Instead, EISs and message providers can plug any message provider, including their own custom or proprietary message providers, into a Java EE server.

To provide this feature, a message provider or an EIS resource adapter implements the messaging contract, which details APIs for message handling and message delivery. A conforming resource adapter is assured of the ability to send messages from any provider to a message-driven bean, and it also can be plugged into a Java EE server in a standard manner.

Transaction Inflow

The Connector Architecture supports importing transactions from an EIS to a Java EE server. The architecture specifies how to propagate the transaction context from the EIS. For example, a transaction can be started by the EIS, such as the Customer Information Control System (CICS). Within the same CICS transaction, a connection can be made through a resource adapter to an enterprise bean on the application server. The enterprise bean does its work under the CICS transaction context and commits within that transaction context.

The Connector Architecture also specifies how the container participates in transaction completion and how it handles crash recovery to ensure that data integrity is not lost.

Metadata Annotations

Java EE Connector Architecture 1.6 introduces a set of annotations to minimize the need for deployment descriptors.

The specification allows a resource adapter to be developed in mixed-mode form, that is the ability for a resource adapter developer to use both metadata annotations and deployment descriptors in applications. An application assembler or deployer may use the deployment descriptor to override the metadata annotations specified by the resource adapter developer.

A new attribute, metadata-complete, is introduced in the Connector 1.6 deployment descriptor (the ra.xml file). The metadata-complete attribute defines whether the deployment descriptor for the resource adapter module is complete, or whether the class files available to the module and packaged with the resource adapter need to be examined for annotations that specify deployment information.

For the complete list of annotations and JavaBeans components introduced in Java EE 6, see http://jcp.org/en/jsr/detail?id=322.

Replacing Deployment Descriptors With Metadata Annotations

The use of annotations reduces or completely eliminates the need to deal with a deployment descriptor in many cases. The use of annotations also reduces the need to keep the deployment descriptor synchronized with changes to source code.

The following examples provide sample deployment descriptors and equivalent annotations.

Example 1: @Connector Annotation

The following deployment descriptor defines a connector:

<connector xmlns "http://java.sun.com/xml/ns/j2ee"
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_6.xsd" 
version="1.6">
<description>Sample adapter using the JavaMail API</description>
<display-name>InboundResourceAdapter</display-name>
<icon></icon>
<vendor-name>Sun Microsystems, Inc</vendor-name>

<eis-type>MAIL</eis-type>
<resourceadapter-version>1.0</resourceadapter-version>
...
...
...
<authentication-mechanism>
	<authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
<credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
</authentication-mechanism>
<reauthentication-support>false</reauthentication-support>
...
...
</connector>

The equivalent metadata annotation is as follows:

@Connector(
description = "Sample adapter using the JavaMail API",
   displayName = "InboundResourceAdapter",
   vendorName = "Sun Microsystems, Inc.",
    eisType = "MAIL",
    version = "1.0",
   authMechanisms = {
                @AuthenticationMechanism(
          authMechanism = "BasicPassword",
credentialInterface = AuthenticationMechanism.CredentialInterface.PasswordCredential
                )
        }

/*
 // Since the following attribute values denote the default values of the annotation,
 // they need not be specified explicitly

 transactionSupport = TransactionSupport.TransactionSupportLevel.NoTransaction,
    reauthenticationSupport = false
*/
)

public class ResourceAdapterImpl 
implements ResourceAdapter, java.io.Serializable
{
...
...
}

Example 2: @ConnectionDefinition Annotation

The following deployment descriptor snippet describes a connection definition:

<connection-definition>
<managedconnectionfactory-class>
samples.mailra.ra.outbound.ManagedConnectionFactoryImpl
</managedconnectionfactory-class>
<config-property><config-property-name>serverName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>UnknownHostName</config-property-value>

...
...
<connectionfactory-interface>samples.mailra.api.JavaMailConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>samples.mailra.ra.outbound.JavaMailConnectionFactoryImpl</connectionfactory-impl-class>
<connection-interface>samples.mailra.api.JavaMailConnection</connection-interface>
<credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
<connection-impl-class>samples.mailra.ra.outbound.JavaMailConnectionImpl</connection-impl-class>
</connectiondefinition>

The equivalent metadata annotation is as follows:

@ConnectionDefinition(
        connectionFactory = 
samples.mailra..api.JavaMailConnectionFactory.class,
        connectionFactoryImpl = 
samples.mailra.ra.outbound.JavaMailConnectionFactoryImpl.class,
        connection = samples.connectors.mailconnector.api.JavaMailConnection.class,
        connectionImpl = 
samples.mailra..ra.outbound.JavaMailConnectionImpl.class
)
public class ManagedConnectionFactoryImpl implements
    ManagedConnectionFactory, Serializable
{
...
...
 @ConfigProperty(
          defaultValue = "UnknownHostName"
    )
    public void setServerName(String serverName)
    {
       ...
    }

}

Example 3: @Activation Annotation

The following deployment descriptor snippet describes the messaging capabilities of a resource adapter:

<messageadapter>
<messagelistener>
<messagelistener-type>samples.mailra.api.JavaMailMessageListener</messagelistener-type>
<activationspec>
<activationspec-class>samples.mailra.ra.inbound.ActivationSpecImpl</activationspec-class>
required-config-property>
	<config-property-name>serverName</config-property-name>
</required-config-property>
<required-config-property>
	<config-property-name>userName</config-property-value>
</required-config-property>
<required-config-property>
	<config-property-name>password</config-property-value>
</required-config-property>
<required-config-property>
<config-property-name>folderName</config-property-value>
</required-config-property>
<required-config-property>
<description>Normally imap or pop3</description>
<config-property-name>protocol</config-property-name>
<config-property-value>IMAP</config-property-value>
</required-config-property>
</activationspec>
</messagelistener>
</messageadapter>

The equivalent metadata annotation is as follows:

@Activation(
        messageListeners = {samples.mailra.api.JavaMailMessageListener.class}

)
public class ActivationSpecImpl implements javax.resource.spi.ActivationSpec,
                                           java.io.Serializable
{
...
 @ConfigProperty()
    // serverName property value
    private String serverName = new String("");

    @ConfigProperty()
    // userName property value
    private String userName = new String("");

    @ConfigProperty()
    // password property value
    private String password = new String("");

    @ConfigProperty()
    // folderName property value
    private String folderName = new String("Inbox");

    // protocol property value
    // Normally imap or pop3
    @ConfigProperty(
            description = "Normally imap or pop3"
    )
    private String protocol = new String("imap");


...
...
}

Common Client Interface

This section describes how components use the Connector Architecture Common Client Interface (CCI) API and a resource adapter to access data from an EIS.

Defined by the Java EE Connector Architecture specification, the CCI defines a set of interfaces and classes whose methods allow a client to perform typical data access operations. The CCI interfaces and classes are as follows:

A client or application component that uses the CCI to interact with an underlying EIS does so in a prescribed manner. The component must establish a connection to the EIS's resource manager, and it does so using the ConnectionFactory. The Connection object represents the actual connection to the EIS and is used for subsequent interactions with the EIS.

The component performs its interactions with the EIS, such as accessing data from a specific table, using an Interaction object. The application component defines the Interaction object using an InteractionSpec object. When the application component reads data from the EIS (such as from database tables) or writes to those tables, it does so using a particular type of Record instance: either a MappedRecord, an IndexedRecord, or a ResultSet instance. Just as the ConnectionFactory creates Connection instances, a RecordFactory creates Record instances.

Note, too, that a client application that relies on a CCI resource adapter is very much like any other Java EE client that uses enterprise bean methods.

Further Information about Resources

For more information about resources and annotations, see: