Sun Java Solaris Communities My SDN Account Join SDN
 
Article

Using the J2EE Connector Architecture Common Client Interface

 
 


This article describes the J2EE Connector architecture Common Client Interface (CCI) API. The CCI provides the access from J2EE clients, such as enterprise beans, JavaServer Pages (JSP) technology, and servlets, to an underlying enterprise information system (EIS). The J2EE Connector architecture, and the CCI API, are currently available as a beta release.

The CCI simplifies the problem of writing code to connect a client to an underlying EIS's data store. This problem exists for both application developers and for EIS vendors. The EIS vendor can use the CCI to write a generic interface to its database product. With this one interface, their product will work with clients on any compliant J2EE platform. Likewise, application developers only need to learn and use one set of API calls to connect their client to any underlying EIS, rather than having to learn a different API for each EIS. In addition, even if an enterprise changes its underlying EIS, its application code will not have to be changed to maintain this connectivity.

Introduction to the CCI

To access an EIS from a J2EE client, you need to first establish and define a connection to the EIS. The term EIS refers to a data store or database, or other mechanism that stores data on an enterprise scale. (For simplicity, this article uses the term database to refer to any kind of data store.) For each operation you want to perform on the data store or database, you establish and define an interaction. You also create a record for transferring data into or out of the database. Rather than directly access the EIS, clients use the CCI to interact with a resource adapter, which is a software component provided by an EIS vendor for a specific EIS.

By designing resource adapters that comply with the specifications of the Connector architecture, EIS vendors make it possible for developers to write transportable code for accessing EISs without having to know the underlying semantics of the resource manager that handles the EIS.

CCI Elements

These are the Java classes defined in the CCI and some of the more important methods for performing database operations.

  • ConnectionFactoryEstablishes a connection instance with EIS
    • getConnection creates a Connection instance (managed by either a container or a component)
    • getRecordFactory creates a RecordFactory instance
  • ConnectionRepresents a connection (using the resource adapter) to an EIS
    • createInteraction creates an Interaction object so that database operations can be performed
    • getLocalTransaction creates a LocalTransaction object
    • close closes a connection to EIS
  • ConnectionSpecDefines user name, password, and other properties in a connection request; serves as properties parameter
  • InteractionCreates an interaction with the connected EIS
    • executeinvokes procedures stored in an EIS for performing database operations
  • InteractionSpecDefines an interaction with the connected EIS, including schema, catalog, and stored function names
  • RecordFactoryCreates Record object
    • createIndexedRecord creates an ordered collection of Record instances
    • createMappedRecord creates a collection of Record instances ordered by key-value pairs
    • createResultSet creates a collection of Record instances as a result set of tabular data
  • RecordSuperclass for Record instances
    • add adds data to input record
  • LocalTransactionEstablishes a context for a local transaction
    • begin starts a database transaction
    • commit completes an atomic database transaction
    • rollback cancels transaction, returning database to initial state

There is a prescribed manner that a client or application component must follow to use the CCI to interact with an underlying EIS. The component must establish a connection to the EIS's resource manager using the ConnectionFactory. The Connection object represents the actual connection to the EIS and is used for subsequent interactions with the EIS. The ConnectionSpec object defines the connection request information, that is, the user name, password, and any other needed properties.

The component performs its interactions with the EIS, such as accessing data from a specific table, using an Interaction object. The InteractionSpec object defines the Interaction object, specifying the database schema and catalog and any predefined database operations stored in the database. When the application component reads data from the EIS (such as from database tables) or writes to those tables, it uses a Record instance, (a MappedRecord, IndexedRecord, or ResultSet instance) instantiated by the RecordFactory object.

An application component uses the LocalTransaction object only when it manages its own transaction and persistence. For example, an enterprise bean can choose to use bean-managed persistence (BMP), in which case it manages its own transactions. However, if the bean uses container-managed persistence (CMP), then the bean lets the container completely handle the transaction and it has no need to use the LocalTransaction object. The LocalTransaction object enables the data access to be conducted as an all-or-nothing transaction.

Steps in Using a Connector

The basic programming steps in using the CCI API and a connector to access a database or data store are:

  • Establish a JNDI context for your session. User name and password are required to access the EIS.
  • Use the JNDI lookup method to locate the ConnectionFactory for the resource adapter.
  • Use the ConnectionFactory method getConnection to open the connection.
  • Use the Connection method createInteraction to create a new Interaction instance. All operations on the underlying EIS are done through an Interaction object.
  • Instantiate an object representing the InteractionSpec interface.
  • Use the ConnectionFactory method getRecordFactory to get a reference to the RecordFactory.
  • Create Record instances as necessary using the appropriate RecordFactory create method, such as createIndexedRecord. Be sure to establish whether the record is for input, output, or both input and output (inout).
  • If you are managing your own transaction and persistence, begin a transaction so that you can recover if a problem occurs.
  • Perform the desired operation on the data store. The example in this article uses database stored procedures to operate on the database. Note that the elements in the Record instances need to map to the appropriate parameters in the stored procedures.
  • If you manage your own transaction, commit the transaction or rollback if there are errors.
  • Close the connection to the EIS.

Overview of the Example of a Session Bean Using a Resource Adapter

This example shows how a session bean uses a resource adapter to add and read records in a relational database. The example shows how to invoke stored procedures, which are business logic functions stored in a database and specific to an enterprise's operation. Stored procedures consist of SQL code to perform operations related to the business needs of an organization. They are kept in the database and can be invoked when needed, just as you might invoke a Java method. In addition to showing how to use the CCI to invoke stored procedures, the Example also illustrates how to pass parameters to stored procedures and how to map the parameter data types from SQL to Java.

You should have already installed the resource adapter for the EIS and its connection factory. Refer to the J2EE reference implementation documentation for instructions on how to do this.

The example session beanAcctManage is like any other session bean. It has a home interface (AcctManageHome.java), a remote interface (AcctManage.java), and an implementation class (AcctManageEJB.java). The client is AcctManageClient.java.

The AcctManage home interface is like any other session bean home interface it extends EJBHome and defines a create method to return a reference to its remote interface. The AcctManage remote interface defines the bean's two methods that may be called by a client:

public void insertAcct(String acctName, int amt) 
                            throws RemoteException;

public int getAcctAmt() throws RemoteException;

Using Database Stored Procedures

Before going further, it is important to understand database stored procedures. This example shows you how to invoke a database stored procedure; it is the stored procedure that actually reads or writes to the database.

A stored procedure is a business logic method or function that is stored in a database and is specific for the enterprise's business. Typically, stored procedures are written in SQL code, though in certain cases (such as with Cloudscape) they may actually be written in Java code. Stored procedures perform operations related to the business needs of an organization. They are kept in the database and applications can invoke them when needed.

Stored procedures are typically SQL statements. This example calls two stored procedures: GETAMT and ADDACCT. The GETAMT procedure merely gets the account amounts from records in the Account table, as follows:

SELECT AMT(*) FROM ACCOUNT

The ADDACCT procedure adds an account record to the table. The record has two values, which are passed to the procedure as parameters:

INSERT INTO ACCOUNT VALUES (?,?)

Defining Input and Output Parameters

When you invoke a stored procedure from your application component, you may have to pass argument values to the procedure. For example, when you invoke the ADDACCT procedure, you pass it two values for the Account record elements. Likewise, you must be prepared to receive values that a stored procedure returns.

  • The stored procedure, in turn, passes its set of parameters to the database manager (DBMS) to carry out its operation and may receive values back from the DBMS.
  • Database stored procedures specify, for each of their parameters, the SQL type of the parameter value and the mode of the parameter.
  • Mode can be input (IN), output (OUT), or both input and output (INOUT).
  • An input parameter only passes data in to the DBMS while an output parameter only receives data back from the DBMS.
  • An INOUT parameter accepts both input and output data.

When you use the CCI execute method to invoke a database stored procedure, you also create an instance of an InputRecord if you're passing a parameter to the stored procedure and, if the stored procedure you're executing returns data, possibly an OutputRecord instance. The InputRecord and OutputRecord are instances of the supported Record types: IndexedRecord, MappedRecord, or ResultSet. In this example, it instantiates an InputRecord and an OutputRecord that are both IndexedRecord instances.

The InputRecord maps the IN and INOUT parameters for the stored procedure, while the OutputRecord maps the OUT and INOUT parameters. Each element of an input or output record corresponds to a stored procedure parameter. That is, there is an entry in the InputRecord for each IN and INOUT parameter declared in the stored procedure. Not only does the InputRecord have the same number of elements as the procedure's input parameters, they are declared in the same order as in the procedure's parameter list. The same holds true for the OutputRecord, though its list of elements matches only the OUT and INOUT parameters.

For example, suppose you have a stored procedure X that declares three parameters. The first parameter is an IN parameter, the second is an OUT parameter, and the third is an INOUT parameter. Figure 1 shows how the elements of an InputRecord and an OutputRecord map to this stored procedure.

CCI

Figure 1: Mapping Stored Procedure Parameters to CCI Record Elements

You must declare the parameter type and mode before calling a stored procedure with parameters. Keep in mind, though, that you may have to declare the parameter mode differently depending on the underlying DBMS. Oracle designates the parameter's mode in the stored procedure declaration, along with the parameter's type declaration. For example, an Oracle ADDACCT procedure declares its two IN parameters as follows:

procedure ADDACCT (
acctname IN VARCHAR2, amt IN INTEGER)

An Oracle GETAMT procedure declares its parameter amt as an OUT parameter:

procedure GETAMT (amt OUT INTEGER)

Cloudscape, which declares stored procedures using a standard Java method signature, indicates an IN parameter using a single value and an INOUT parameter as an array. The method's return value is the OUT parameter. For example, Cloudscape declares the IN parameters (acctName and amt) for ADDACCT and the OUT parameter (the method's return value) for GETAMT follows:

public static void ADDACCT(String acctname, int amt)

public int GETAMT()

If amt was an INOUT parameter, then Cloudscape declares it as:

public static void ADDACCT(String acctname, 
                                   int[] amt)

Oracle declares an INOUT parameter as:

procedure ADDACCT (acctname IN VARCHAR2, 
                             amt INOUT INTEGER)

Mapping Java Types to SQL Types

Remember to map the SQL type of each value to its corresponding Java type. Thus, if the SQL type is integer, then the InputRecord or OutputRecord element must be defined as a Integer object. If the SQL type is a VARCHAR, then the Java type must be a String object. When you add the element to the Record, you declare it to be an object of the proper type. For example, add an integer and a string element to an InputRecord as follows:

iRec.add (new Integer (intval));
iRec.add (new String ("Customer Account"));

The JDBC specification defines the complete SQL to Java type mapping.

Programming with the CCI

To illustrate how to use the CCI API, take a look at a session bean and a client of that bean. These pieces of code illustrate how clients invoke the different CCI methods that resource adapters built on CCI might make available. (This example uses the sample resource adapters supplied with the J2EE reference implementation.)

Now examine the session bean implementation class to see how it uses the CCI. To begin with, notice that AcctManageEJB imports the javax.resource CCI interfaces and classes, along with javax.resource.ResourceException:

import javax.resource.cci.*;
import javax.resource.ResourceException;

Getting the Connection

Prior to obtaining a database connection, the AcctManageEJB session bean does some set up work in its setSessionContext method. Specifically, the setSessionContext method sets the user and password values, and instantiates a ConnectionFactory. These values and objects remain available to the other session bean methods.

public void setSessionContext(SessionContext sc) {
  try {
    this.sc = sc;
    // Establish a JNDI initial context.
    Context ic = new InitialContext();
    // Use the JNDI InitialContext.lookup 
    //method to find the user 
    // and password values.
    user = (String) ic.lookup("java:comp/env/user");
    password = 
       (String) ic.lookup("java:comp/env/password");
    // Use the lookup method to locate the 
    // ConnectionFactory for the CCI 
    // resource adapter and obtain a reference to it.
    cf = (ConnectionFactory) 
               ic.lookup("java:comp/env/CCIEIS");
...

AcctManageEJB uses its private method getCCIConnection to establish a connection to the underlying resource manager or database. An AcctManage client cannot invoke this method directly. Rather, the session bean uses this method internally to establish a connection to the database. The getCCIConnection method invokes the getConnection method to obtain the connection. Prior to this call, it instantiates a CciConnectionSpec object, which represents the implementation of the ConnectionSpec interface, with the user and password values. It uses this CciConnectionSpec object to pass the user and password values to the connection.

private Connection getCCIConnection() {
  Connection con = null;
   try {
	// Instantiate a new CciConnectionSpec 
	// object with the user and
	// password values obtained by the 
	// setSessionContext method. The
	// CciConnectionSpec class is the 
	// implementation of the 
	// ConnectionSpec interface.
	ConnectionSpec spec = 
	   new CciConnectionSpec(user, password);
	// Call the ConnectionFactory's getConnection
	// method to obtain a connection 
	to the database.
	// Use the CciConnectionSpec object to
	// pass the required properties to 
	// the ConnectionFactory. The getConnection 
	// method returns a Connection object.
	con = cf.getConnection(spec);
   } catch (ResourceException ex) {
	...
  }
  return con;
}

The AcctManageEJB bean also includes a private method, closeCCIConnection, to close a connection. The method invokes the Connection object's close method from within a try/catch block. Like the getCCIConnection method, this is a private method intended to be called from within the session bean.

private void closeCCIConnection(
Connection con) {
        try {
            con.close();
        } catch (ResourceException ex) {
            ex.printStackTrace();
        }
    }

Reading Database Records

The AcctManageEJB's getAcctAmt method illustrates how to use the CCI to read records from a database table. This method does not directly read the database records itself; instead, it invokes a procedure stored in the database called GETAMT. It is the stored procedure that actually reads the records in the database table.

The CCI provides interfaces for three types of records: IndexedRecord, MappedRecord, and ResultSet. These three record types inherit from the base interface, Record. They differ only in how they map the record elements within the record. The example uses IndexedRecord. IndexedRecord holds its record elements in an ordered, indexed collection based on java.util.List. As a result, a Iterator is used to access the individual elements in the list.

Begin by looking at how the getAcctAmt method uses the CCI to invoke a database stored procedure. The method first obtains a connection, then creates a new Interaction instance by calling the Connection object's createInteraction method. The Interaction object enables a bean to execute EIS functions such as invoking stored procedures.

public int getAcctAmt() {
  int count = -1;
  try {
	// Obtain a connection to the database.
 	Connection con = getCCIConnection();
	// Create a new Interaction instance
	// so that the session bean can invoke
	// the EIS stored procedure.
 	Interaction ix = con.createInteraction();
...

Then, the bean must instantiate a CciInteractionSpec object to pass properties to the Interaction object. The CciInteractionSpec is the implementation class for the InteractionSpec interface, and it holds properties required by the Interaction object to interact with an EIS instance. Such properties include schema name, catalog name, and the stored procedure name. The session bean uses the CciInteractionSpec methods setSchema, setCatalog, and setFunctionName to set the required values into the instance's fields. This example passes GETAMT to setFunctionName because this is the name of the stored procedure it intends to invoke.

  ...
  // Instantiate a CciInteractionSpec object.
  CciInteractionSpec iSpec =
  new CciInteractionSpec();
  // Set values for the CciInteractionSpec 
  instance's
  //fields: user name and stored procedure name. Our
  //example uses a Cloudscape database, 
  which does not
  // require a catalog name.
  iSpec.setSchema(user);
  iSpec.setCatalog(null);
  iSpec.setFunctionName("GETAMT");
 ...

Now, the getAcctAmt method uses the ConnectionFactory to obtain a reference to a RecordFactory. With the RecordFactory reference, it invokes the createIndexedRecord method to create an IndexedRecord instance. (The bean could also use the RecordFactory to create MappedRecord or ResultSet instances.) It creates the IndexedRecord using the name InputRecord, which it passes to createIndexedRecord as an argument. This completes the set up work that must be done prior to invoking the stored procedure.

  ...
  // Obtain a RecordFactory reference.
  RecordFactory rf = cf.getRecordFactory();
  // Invoke the RecordFactory's
  // createIndexedRecord method.
  IndexedRecord iRec =
      rf.createIndexedRecord("InputRecord");
  ...

The getAcctAmt method uses the Interaction instance's execute method to invoke the stored procedure GETAMT. The bean passes two objects to the execute method: the InteractionSpec object, whose properties reference the GETAMT stored procedure, and the IndexedRecord object, which is expected to be an input Record. The execute method returns an output Record object.

  ...
  // Use the Interaction instance's execute
  // method to invoke GETAMT.
  oRec =ix.execute(iSpec,iRec);
  ...

Then, the bean uses an Iterator to retrieve the individual elements from the Record returned by the execute method. It first casts the output Record object to an IndexedRecord. Note that IndexedRecord contains an iterator which it inherits from java.util.List. The bean uses the iterator.hasNext method to retrieve each element in the returned record object. Each extracted element is an Object, and the bean evaluates whether it is an integer or decimal value and processes it accordingly. When it has completely processed the record, it closes the connection to the database and returns the results.

    ...
    // Retrieve the individual elements from
    // the returned IndexedRecord using the
    // iterator.hasNext method.
    Iterator iterator =
    ((IndexedRecord)oRec).iterator();
    while(iterator.hasNext()) {
      Object obj = iterator.next();
      if (obj instanceof Integer) {
   		amt = ((Integer)obj).intValue();
      }
      else if (obj instanceof BigDecimal) {
	 	amt = ((BigDecimal)obj).intValue();
      }
   }
   // Close the connection to the database.
   closeCCIConnection(con);	          
} catch (ResourceException ex) {
...
}
return amt;
}

Inserting Database Records

The AcctManageEJB session bean implements the insertAcct method to add new records into the Account database table. This method invokes the ADDACCT stored procedure, which inserts an account record and sets values for the two elements in the recordaccount name and amountusing values passed to it as arguments.

The insertAcct method shown here illustrates how to use the CCI to invoke a stored procedure that expects to be passed argument values. Much of the set up is the same as what was done in the getAcctAmt method. The method first establishes a connection to the database, then creates a new Interaction instance to execute the stored procedure. The bean also instantiates a CciInteractionSpec object (from the CciInteractionSpec class that implements the InteractionSpec interface) to hold the properties that the Interaction object requires to communicate to the database, then it uses the functions setSchema, setCatalog, and setFunctionName to set the necessary property values. Notice that the method sets the function name to ADDACCT.

public void insertAcct(String acctName, int amt) {
  try {
	// Establish a connection to the database.
	Connection con = getCCIConnection();
	// Create a new Interaction instance
	// to execute the stored procedure.
	Interaction ix = con.createInteraction();
	// Instantiate a CciInteractionSpec object to
	// pass necessary properties to the 
	// Interaction object.
	CciInteractionSpec iSpec = 
	                 new CciInteractionSpec();
	// Set schema, catalog and function name 
	// values in the CciInteractionSpec 
	// object fields.
	iSpec.setFunctionName("ADDACCT");
	iSpec.setSchema(user);
	iSpec.setCatalog(null);
	...

Next, the bean obtains a reference to a RecordFactory using the ConnectionFactory's getRecordFactory method. It then invokes the RecordFactory's createIndexedRecord method to create a new IndexedRecord called InputRecord. At this point, the bean needs to set values for the two elements in the input record that are to be passed to the ADDACCT stored procedure. The bean uses the IndexedRecord object's add method to set up these values in the new record. It calls the add method once for each element. It sets the first record element to the account name value and the second element to the amount value. (Notice that the int value amt is set to an Integer object when it is passed to the add method. The add method accepts only Java objects.) The AcctManageEJB bean is now ready to pass the new account record to the stored procedure which will add it to the database.

It calls the Interaction instance's execute method to invoke the stored procedure ADDACCT. Just as when invoking the GETAMT procedure, the bean passes two objects to the execute method: the InteractionSpec object with the correctly set properties for the ADDACCT stored procedure and the IndexedRecord object representing an input Record. The execute method is not expected to return anything in this case.

The method completes by closing the connection to the database.

	...
	// Obtain a reference to a RecordFactory.
	RecordFactory rf = cf.getRecordFactory();
	// Create a new IndexedRecord called
	// InputRecord.
	IndexedRecord iRec = 
	   rf.createIndexedRecord("InputRecord");
	// Use the IndexedRecord add method to
	// add acctName and amt to
	// the input record. 
	boolean flag = iRec.add(name);
	flag = iRec.add(new Integer(qty));
	// Invoke the Interaction execute method
	// to invoke the ADDACCT stored procedure
	ix.execute(iSpec,iRec);
	// Close the connection to the database.
	closeCCIConnection(con);
}catch (ResourceException ex) {
	ex.printStackTrace();
}
}

Executing a Local Transaction

The previous sections showed how to program with the CCI from an EJB that uses container-managed persistence. Because the EJB container ensured that the database access would take place within the context of a transaction, an AcctManage bean using container-managed persistence did not have to concern itself with these matters. The container handled starting and ending the transaction, making sure that the database record was updated without interference from other processes.

However, if your bean uses bean-managed persistence, then it must handle its own transaction. An enterprise bean with bean-managed persistence uses methods from the LocalTransaction interface to handle local transactions.

Keep in mind that resource managers typically support two types of transactions: XA transactions and local transactions. XA transactions refer to the Java mapping of the X/Open XA protocol. They are often called global transactions, because they can span multiple resource managers. Typically, XA transactions are managed by an external transaction manager located on the application server.

Local transactions, on the other hand, are managed by the resource manager itself, and you can use the CCI API to handle a local transaction. To ensure the integrity of the data, add a record to the database from within the context of a transaction. To illustrate, look at the modified the AcctManage bean's insertAcct method that uses the CCI to start and commit, or rollback, a local transaction.

public void insertAcct(
String acctName, int amt) {
  try {
	Connection con = getCCIConnection();
	Interaction ix = con.createInteraction();
	CciInteractionSpec iSpec = 
	                new CciInteractionSpec();
	iSpec.setFunctionName("ADDACCT");
	iSpec.setSchema(user);
	iSpec.setCatalog(null);
	RecordFactory rf = cf.getRecordFactory();
	IndexedRecord iRec = 
	     rf.createIndexedRecord(
	     "InputRecord");
	boolean flag = iRec.add(acctName);
	flag = iRec.add(new Integer(amt));

	// Obtain a reference to a transaction 
	// context
	LocalTransaction transaction = 
	                con.getLocalTransaction();
	// Start the transaction
	transaction.begin();
	try {
		ix.execute(iSpec, iRec);
		// The operation was successful; 
		// commit the transaction
		transaction.commit();
	} catch (ResourceException e) {
		// An error occurred; rollback 
		// the transaction
		transaction.rollback();
	}

	closeCCIConnection(con);
}catch(ResourceException ex) {
	ex.printStackTrace();
}
}

As you can see, most of the code of the insertAcct method is identical to the container-managed persistence version: Both versions do the following, in the same order:

  • Obtain a connection to the database.
  • Create an Interaction object.
  • Create and define properties for an object that implements the InteractionSpec interface.
  • Use the ConnectionFactory to obtain a reference to the RecordFactory.
  • Create an IndexedRecord input Record and sets the values for the two elements in the Account record: account name and amount.

At this point, the bean-managed persistence version deviates from the container-managed version. Before invoking the Interaction object's execute method, the bean first obtains a reference to a transaction. To do this, it invokes the Connection object's getLocalTransaction method and instantiates a new LocalTransaction object. The LocalTransaction object provides the context for the transaction. Then, the bean starts the transaction by invoking the LocalTransaction object's begin method.

  ...
  // Obtain a reference to a transaction context
  LocalTransaction transaction = 
	              con.getLocalTransaction();
  // Start the transaction
  transaction.begin();
  ...

The bean can now safely do its transactional work. In this case, it invokes the Interaction object's execute method to execute the stored procedure ADDACCT and insert the new Account record into the database. The call to execute is the same as in the container-managed version, except that it is made from within a try block to catch any errors. If the call to execute is successful, then the bean commits the transaction. Otherwise, it rolls back the transaction to undo its actions. When a transaction is rolled back, any changes made to the database are undone and the database is restored to the state it was in prior to the start of the transaction.

	...
	try {
		ix.execute(iSpec, iRec);
		transaction.commit();
	} catch (ResourceException e) {
		transaction.rollback();
	}
	// Close the connection
	...

The insertAcct method finishes by closing the connection.

Writing a CCI Client

A client application that relies on a CCI resource adapter is very much like any other J2EE client application. The AcctManageClient application uses the methods of the AcctManageEJB session bean to access the Account table in the underlying database. AcctManageClient invokes the AcctManage getAcctAmt method to read account amounts from the Account table and the insertAcct method to add records to the table.

Conclusion

By now, you should have a good understanding of how to use the J2EE Connector architecture's Common Client Interface API. You've seen how to use the different interfaces and classes defined by the CCI to access a resource adapter for an underlying database or EIS. You've also seen how to use these methods to invoke procedures stored in the EIS, and to pass parameters to these procedures and receive values back.

The Connector architecture and the CCI are currently supported by a significant number of J2EE-compliant EIS vendors and tools vendors. It is anticipated that most, if not all, J2EE-compliant EIS vendors will support this technology. As its use becomes more widespread, and particularly as more and more tools vendors build support of the CCI into their tools, it will become the standard for J2EE enterprise application connectivity.

Coffecup Logo

About the Author

Beth Stearns is the principal partner of ComputerEase Publishing, a computer consulting firm she founded in 1982. Her client list includes Sun Microsystems, Inc., Silicon Graphics, Inc., Oracle Corporation, and Xerox Corporation. Among her publications are the "Java Native Interface" chapter in "The Java Tutorial Continued" book in the Addison Wesley Java series, "The EJB Programming Guide" for Inprise Corporation, and "Understanding EDT", a guide to Digital Equipment Corporation's text editor. Most recently, she is co-author with Vlada Matena of the forthcoming Addison Wesley Java series book, "Applying Enterprise JavaBeans: Component-Based Development for the J2EE Platform."