Skip to main content

Build JCA-compliant resource adapters with WebSphere Studio Application Developer

Michael McMahon (mmcmaho@us.ibm.com), Advisory Software Engineer, IBM, Software Group
Michael McMahon is an Advisory Software Engineer currently working as a scenario solution developer and tester in the WebSphere System House at IBM in Raleigh, North Carolina. He has previously worked in the IBM WebSphere Edge Server team on load balancing and video streaming technology, and on a mix of video and database projects prior to that. Contact Michael at mmcmaho@us.ibm.com.
Mikhail Genkin (genkin@ca.ibm.com), Certified IT Architect, IBM, Software Group
Mikhail Genkin is a Technical Solution Designer working with the IBM WebSphere System House group at the IBM Toronto Software Development lab. His work involves conducting expert reviews of IBM and competitor tools for Java and Web service-based enterprise access. He advises several IBM development teams building WebSphere tools for J2EE, Web services, RDBMS and EIS access about the usability, performance, and interoperability aspects of their products. He has contributed to several releases of VisualAge for Java, Enterprise Edition; WebSphere Application Developer; and WebSphere Application Developer - Integration Edition.

Mikhail Genkin holds a bachelor's degree in Geophysics from Carleton University, Ottawa, Canada, and an M.Sc. in Earth Sciences from University of Ottawa. He is a Sun Certified Java Programmer, and an IBM Certified Developer Associate - IBM VisualAge for Java. You can contact him at genkin@ca.ibm.com.

Summary:  Java Connector Architecture (JCA) is a standard that provides a uniform method for talking to different kinds of Enterprise Information Systems (EIS) from an application server. JCA is designed to facilitate sharing of data and to integrate new J2EE applications with legacy or other heterogeneous systems. In this article, the authors use a sample scenario to show how you can use IBM WebSphere Studio Application Developer to help debug, unit test, build, and deploy a JCA-compliant resource adapter.

Date:  01 Aug 2003
Level:  Intermediate
Activity:  2241 views

Introduction

This article assumes you're familiar with the basic concepts of JCA development. JCA is designed to facilitate sharing of data and to integrate new J2EE applications with legacy or other heterogeneous systems. It stipulates how the EIS vendor can develop a resource adapter that can plug into any J2EE-compliant application server.

In this article we'll describe how you can leverage IBM tools to speed up the development cycle for resource adapters. We use IBM WebSphere Studio Application Developer (Application Developer) V5.0 as our development and test environment. Extensive experience with Application Developer is not necessary, although basic familiarity with the integrated development environment (IDE) would be beneficial. If you want to follow along with the example, you'll need to install Application Developer. You can download a trial copy of the latest version from the developerWorks download site.

We will use a sample resource adapter to show how you can use Application Developer to help debug, unit test, build, and deploy a resource adapter. We'll also explain how to use Application Developer import/export tools to:

  • Work with RAR files.
  • Write adapter code.
  • Use the integrated debugger and Universal Test Client to unit test and debug resource adapter source in both a managed and non-managed setting.

Getting ready

To show Application Developer's capabilities we'll use the CciBlackBox, one of the sample resource adapters provided by Sun Microsystems. As shown in the following steps, this basic adapter demonstrates the implementation of the JCA standard by providing connectivity to a relational database and execution of stored procedures:

  1. Get the source code for the CciBlackBox adapter from Sun's site. The zip file containing the adapter code is named j2ee_connector-1_0_1-sample_adapters.zip.
  2. Unzip the contents of j2ee_connector-1_0_1-sample_adapters.zip to a temp directory. For this example, we use cciblackbox-tx.rar, the adapter version that supports local transactions only.
  3. Note the src/CciBlackBox directory located under the sample-adapters directory. Import the files under this directory into your Application Developer workspace.

The adapter makes use of Java Database Connectivity (JDBC) technology under the covers. Our CciBlackBox adapter will be executing a stored procedure from a DB2 database system. To proceed with the subsequent tasks, you'll need to set up a sample database, as shown below in Figure 2. The script at the top can be used to set up the user ID, table, and stored procedure in the RDBMS that we will use in this scenario. The Java source for the stored procedure is also included in the lower part of Listing 1. The stored procedure accepts two parameters. An input variable itemnumberIn (type varchar) is used to perform a record lookup. The output variable priceOut (type number ) is used to receive the price of the item in question.

You can use the following DDL script to set up your sample database in DB2. You could also easily modify it to work with other databases, such as Oracle.


Listing 1. Sample DDL script and Java source code
-- Start of DDL Script -------------------
-- Sample script for creating the PARTS database
-- DB2 UDB, v.8.1
-- Re-create the sample PARTS database

-- Sample script for creating the PARTS database
-- DB2 UDB, v.8.1
-- Re-create the sample PARTS database

create database PARTS;

connect to PARTS;

GRANT CREATETAB,BINDADD,CONNECT,CREATE_NOT_FENCED_ROUTINE,
   IMPLICIT_SCHEMA,CREATE_EXTERNAL_ROUTINE ON DATABASE  TO USER testuser;
   
connect to PARTS user testuser using t3stus3r;

create table PRICE (ITEMNUM varchar(32) not null primary key, PARTNUM
   varchar(32), SUPPLID varchar(32), COST double);

-- Insert some sample data

insert into PRICE (ITEMNUM, PARTNUM, SUPPLID, COST) values ('IN1111111', 
   'PN1111111', 'SI0000001', 2.05);
   	
insert into PRICE (ITEMNUM, PARTNUM, SUPPLID, COST) values ('IN1111112', 
   'PN1111112', 'SI0000001', 5.45);
   
insert into PRICE (ITEMNUM, PARTNUM, SUPPLID, COST) values ('IN1111113', 
   'PN1111113', 'SI0000002', 10.15);
   
-- Create the stored procedure
CREATE PROCEDURE getPartPrice ( IN itemnumberIn VARCHAR(32), 
                                   OUT priceOut DOUBLE )
    NOT DETERMINISTIC
    LANGUAGE Java
    EXTERNAL NAME 'GetPartPrice.getPartPrice'
    FENCED
    PARAMETER STYLE JAVA;
-- End of DDL Script --------------------------------------

   ______________________________________
   ______________________________________


/* This is the start of the JDBC Stored Procedure getPartPrice
 * @param itemnumberIn Item number for the part.
 * @param priceOut Price of the part with this item number.
 */
import java.sql.*;                   // JDBC classes

public class GetPartPrice
{
    public static void getPartPrice ( String itemnumberIn,
                                      double[] priceOut ) throws 
                                         SQLException, Exception
    {
        // Get connection to the database
        Connection con = DriverManager.getConnection("jdbc:default:
           connection");
        PreparedStatement stmt = null;
        ResultSet rs1 = null;
        boolean bFlag;
        String sql;

        sql = "SELECT PRICE.COST FROM PRICE WHERE PRICE.ITEMNUM = ?";
            
        stmt = con.prepareStatement( sql );
        stmt.setString( 1, itemnumberIn );
        bFlag = stmt.execute();
        rs1 = stmt.getResultSet();
        
        double tmpPrice = 0.0;
        int i = 0;

        // Access query results
        while (rs1.next())
        {
         tmpPrice = rs1.getDouble(1);
         i++;
        }

        // Close open resources
        if (rs1 != null) rs1.close();
        if (stmt != null) stmt.close();
        
        // Should never have more than one price for an item
        if (i > 1)
         throw new SQLException("More than one price returned for item 
            number!");

        // Set return parameter
        priceOut[0] = tmpPrice;
    }
    }

The last step in setting up the stored procedure in the database is to copy the previous Java code into a file called GetPartPrice.java, generate the corresponding class file, and then copy this class file under the DB2 {DB2INSTALLDIR}/SQLLIB/FUNCTION directory. This will enable DB2 to find the Java class when the stored procedure is invoked. You can generate the class file by compiling within Application Developer, or you can use the following command-line invocation: javac GetPartPrice.java.


Importing the adapter source

The CciBlackBox adapter comes in several flavors according to different levels of transactional support. In this article, we'll be working with cciblackbox-tx.rar, which you downloaded in the previous section. This packaging of the CciBlackBox adapter offers support for local transactions (but not for distributed transactions).

One of the most useful features that Application Developer provides for JCA development is the connector project. The connector project in the workspace acts essentially as a resource adapter (RAR) file deployed in a production application server. You can develop and execute code contained in the connector project without leaving the Application Developer IDE, and without performing an explicit deploy step.

To set up a connector project and import the resource adapter source:

  1. Start Application Developer v5.0 and specify tws50_jca as the workspace directory (for example, located under c:\ws_50 directory, if this directory is where you installed WebSphere Studio). The Startup dialog for Application Developer, as shown in Figure 1, lets you specify a new workspace, which will be created when the application loads.
    Figure 1. Startup dialog for Application Developer

  2. Once Application Developer is initialized, open up the Java perspective by selecting Window > Open Perspective > Java
  3. Now select File > Import. Choose RAR File in the list of the Import wizard. Click Next.
  4. The Import RAR wizard, shown in Figure 2, lets you readily import existing resource adapters into the Application Developer IDE. In the Import wizard, you need to select the correct .rar file (in this case, cciblackbox-tx.rar), and provide the name for a new connector project that will be created in the Application Developer workspace as the result. Call your connector project CciBlackBox. Enter this name in the New project name: text box.
    Figure 2. The Import RAR wizard
    The Import RAR wizard
  5. Select Finish to exit the wizard. Notice that a new connector project has been created in the workspace, as shown in Figure 3 below. As you browse the new connector project in the Package Explorer view, you'll see that the project contains the connectorModule folder. This folder contains a META-INF subdirectory, where you'll find the ra.xml deployment descriptor. Also notice that j2ee.jar has been automatically added to the connector project classpath. At this stage, your connector project contains the binaries (connectorModule/CciBlackBox-tx.jar), but not the source code for your adapter. You need to import the source as well.
    Figure 3. New connector project in the Package Explorer view
    New connector project in the Package Explorer view
  6. Right-click on the connectorModule folder in the Package Explorer view. Select Import from the pop-up menu, and File System in the wizard that follows.
  7. In the Import File System wizard, browse to the directory where you unzipped the resource adapter source and select the root directory for import (it should be CciBlackBox). Place a check beside the com subdirectory, as shown in Figure 4, and click Finish.
  8. You don't need the connectorModule/CciBlackBox-tx.jar file attached to your project, so select this JAR in the Package Explorer view, right-click, then select Delete from the pop-up menu.
  9. At this point, you should also add a JDBC JAR file into the connector project that will be needed for access to your DB2 database. Use the import process again to import db2java.zip (the DB2 JDBC driver) into the connectorModule directory in your connector project.
    Figure 4. Importing source from the file system
    Importing source from the file system

You are now ready to begin working with your adapter.


Working with the adapter source

So you can go through the process of editing and recompiling the adapter code in Application Developer, we'll show you how to make a simple enhancement to the CciBlackBox source that will allow your adapter to work better with a third-party relational database system. Adding a new property to the managed connection factory implementation lets you specify the JDBC driver required for connection to the database. This enhancement lets you set the default driver in the deployment descriptor (ra.xml), or when deploying the factory instance, and eliminates the need to hard-code this value in the adapter code or specify a jdbc.system system property in the application server.

To add this property:

  1. Locate the CciLocalTxManagedConnectionFactory.java file in the Project Explorer view. Double-click it with the left mouse button. The Application Developer Java editor opens up, showing the source code for this file.
  2. Add the following code near the top of the CciLocalTxManagedConnectionFactory.java, file as shown in bold in Listing 2 below. You will change CciLocalTxManagedConnectionFactory.java source to include a member variable that will hold the new property value.

    Listing 2. Changes to include a member variable

    public class CciLocalTxManagedConnectionFactory
         implements ManagedConnectionFactory, Serializable {
    	 private String url;
         // DEMOCODE - added for demo
         private String pszDriverName;

  3. Add the getter and setter for your new property near the bottom of the CciLocalTxManagedConnectionFactory.java file, as shown in bold in Listing 3. The setJdbcDriver() method will automatically be called by the application server during initialization of the connection factory (because of the connection factory property JdbcDriver, which you'll add a few steps from now).

    Listing 3. Adding the getter and setter

    public String getConnectionURL() {
        return url;	
    }
    
    public void setConnectionURL(String url) {
        this.url = url;
    }
    
    // DEMOCODE - added for demo
    public String getJdbcDriver() {
        return pszDriverName;
    }
    // DEMOCODE - added for demo
    public void setJdbcDriver(String pszDriver) {
        System.out.println("DEMO-JDBC Driver Setting From JCA CF 
           Config");
    	    this.pszDriverName = pszDriver;
    }

  4. Now you need to modify the createManagedConnection method of the CciLocalTxManagedConnectionFactory.java file, as shown in bold in Listing 4. This code allows the adapter to obtain the JDBC driver from a system property if it is not set as a connection factory property.

    Listing 4. Changes to the createManagedConnection method

    public ManagedConnection
         createManagedConnection(Subject subject,
    	                         ConnectionRequestInfo info)
         throws ResourceException {
    	 
         // DEMOCODE – added for demo
    	 try {
              // If pszDriverName has not been read in from a
              // JCA CF config setting, then try to set it
    		  // here based on the jdbc.drivers system 
    		     property.
              if ( pszDriverName == null ) {
                    pszDriverName = System.getProperty
                       ("jdbc.drivers");
              }
              else {
                  System.out.println(
                       "Using JDBC Driver Setting From JCA CF 
                          Config");
               }
    
               System.out.println("About to register driver");
               DriverManager.registerDriver(
    
    (Driver)Class.forName(pszDriverName).newInstance());
               System.out.println("Registered driver");
    
         } catch (Exception e) {
               e.printStackTrace();
         }        
    	 
            try {
                 Connection con = null;
                 String userName = null;
    			 
                 PasswordCredential pc =
                      Util.getPasswordCredential(this, subject, info);
    
                 if (pc == null) {
                     con = DriverManager.getConnection(url);
                 } else {
    

  5. The final step is adding the default property for JdbcDriver to the adapter's deployment descriptor ra.xml. COM.ibm.db2.jdbc.app.DB2Driver is the JDBC driver class for DB2 that you'll use (you should use an equivalent driver for your RDBMS). This driver resides in the db2java.zip file. This entry is shown in Listing 5 below, and should be added to the ra.xml file in your connector project (under the connectorModule/META-INF folder).

    You also need to modify the ConnectionURL property to contain a value required to connect to a DB2 database system used in this example. This change is also shown in Figure 10, in the bold text above the JdbcDriver entry ("jdbc:db2:parts"). The JdbcDriver entry will show up in the connection factory properties section of the application server admin.

    Listing 5. Changes to the ra.xml deployment descriptor

    <config-property>
        <config-property-name>ConnectionURL</config-property-name>
        <config-property-type>java.lang.String</config-property-type>
        <config-property-value>
            jdbc:db2:parts
        </config-property-value>
    </config-property>
    <config-property>
        <config-property-name>JdbcDriver</config-property-name>
        <config-property-type>java.lang.String</config-property-
           type>
        <config-property-value>
            COM.ibm.db2.jdbc.app.DB2Driver
        </config-property-value>
    </config-property>


Testing and debugging adapter code

You can use several Application Developer features to help with testing and debugging adapter code. Some of the most useful Application Developer features, in addition to the connector project, are the:

  • Integrated debugger
  • Universal Test Environment (UTE)
  • Universal Test Client (UTC).

We will discuss some useful techniques to help you kick-start development.

Most JCA-compliant resource adapters are designed to support both managed and non-managed usage scenarios. In the non-managed case, the resource adapter is used outside of the application server essentially as a library. When you're building a resource adapter, it is usually best to test and debug your code in a non-managed setting first (if, of course, you want to support non-managed use). Invocation semantics of the adapter in the non-managed case are almost identical to the managed case, and many problems (especially with the connection management contract implementation) can be detected and fixed without starting the UTE server. A non-managed test case is very easy to set up. Here's a look at how this can be done in Application Developer.

Testing and debugging in a non-managed environment

To create a simple non-managed test case and use it to debug the connection management contract implementation, you need to complete the following high-level steps.

  1. Create a new Java project.
  2. Create a new Java client class.
  3. Set breakpoints in the adapter code.
  4. Run the Java client class in debug mode.

To create a new Java project:

  1. Select File > New > Project from the main menu.
  2. In the New Project dialog, select Java > Java Project. The New Java Project wizard will be launched. Enter a name for the new project. In this case, call it NonMgdTest. Accept the default settings for the project location and click Next.
  3. On the next page of the wizard, select the Projects tab. Put a check mark beside the CciBlackBox project. This will place your connector project on the classpath of the project used for testing.
  4. Click Finish to create the new project.

Now you need to create a client class that will be used to test your adapter:

  1. Right-click on NonMgdTester project in the Package Explorer view and then select New > Package from the pop-up menu. Give your package a suitable name. (We used com.cciblackbox.tester.) Click Finish to create the package.
  2. To create the Java class, right-click on the package in the Package Explorer view and select New > Class from the pop-up menu. In the New Java Class wizard, give your new class an appropriate name. (We used NonManagedTester.) Select the check box to implement the mainmethod. Accept defaults for all other settings, and click Finish.
  3. Add j2ee.jar to this project's classpath.
  4. The next step, of course, would be to write some code that invokes the target EIS by way of the adapter. The CciBlackBox adapter supports the Common Client Interface (CCI). Listing 6 shows some sample CCI code that can be used to test and debug resource adapter code.

    Listing 6. Sample code to test the CciBlackBox adapter in a non-managed setting

    package com.cciblackbox.tester;
    
    import javax.resource.cci.*;
    import com.sun.connector.cciblackbox.*;
    
    public class NonManagedTester {
    	
      public String getPrice(String itemNumer)
        {
    	  String price = null;
    		
    	// Create and configure a managed connection 
                // factory instance
    		CciLocalTxManagedConnectionFactory mcf = new                
                               CciLocalTxManagedConnectionFactory();
    		 
               mcf.setConnectionURL(
                                 "jdbc:db2:parts");
    		mcf.setJDBCDriver("COM.ibm.db2.jdbc.app.DB2Driver");
    		CciConnectionSpec cspec = new CciConnectionSpec
    		   ("testUser","t3stus3r");
    		CciInteractionSpec ispec = new CciInteractionSpec();
    		ispec.setFunctionName("GETPARTPRICE");
    		
    		try
    		{
    		  // Connect to the EIS (...in our case RDBMS)
    		ConnectionFactory cf = 
                  ((CciConnectionFactory)mcf.createConnectionFactory());
    		Connection cx = cf.getConnection(cspec);
    			
    		 // Execute the stored procedure
    		 Interaction ix = cx.createInteraction();
    		 IndexedRecord input = new CciIndexedRecord();
    		 IndexedRecord output = new CciIndexedRecord();
    		 input.add(0, itemNumer);		
    		 output = (IndexedRecord) ix.execute
    			   (ispec, input);
    		 price = (output.get(0)).toString();
    			
    		}
    		catch(Exception e)
    		{
    			System.out.println(e.getMessage());
    			e.printStackTrace(System.out);
    		}
    		
    		return price;
    	
    	}
    	
    	public static void main(String[] args) {
    		
    		NonManagedTester tester = new NonManagedTester();
    		System.out.println(tester.getPrice("IN1111111"));
    		
    	}
    	
    }
    

The next step is to put breakpoints into sections of code that may be of interest to you, and run your client class in debug mode. When debugging the connection management contract implementation, the createManagedConnection method of the ManagedConnectionFactory implementation offers one of the most important access points for debugging. To debug this method at run time, set a breakpoint.

  1. Expand the connectorModule folder of the CciBlackBox connector project in the Package Explorer view. Expand the com.sun.connector.CciBlackBox package. Locate the file CciLocalTxManagedConnectionFactory.java.
  2. Double-click on this file to open the class in the Java editor. Use the Outline view to navigate to the createManagedConnection method.
  3. Switch to the Java editor. Put the cursor inside the first line in the try/catch block, move the mouse over the left margin of the Java editor, and right-click. Select Add Breakpoint from the pop-up menu. A gray bullet will appear in the left margin of the editor, indicating that the breakpoint has been set.

To run your test class in debug mode:

  1. Browse the NonMgdTester project in the Package Explorer view to find your client class.
  2. Select the NonManagedTester.java file in the Package Explorer. Select Run > Debug from the top-level menu.
  3. In the Launch Configurations dialog, select Java Application from the list. Click New. An entry, NonManagedTester, is added to the list and a set of tabs appear in the right pane of the dialog. You can use these tabs to provide VM arguments to your client, customize source look-up path, and change the JRE and classpath settings prior to launch.
  4. In this case, simply accept the defaults, and click Debug for Application Developer to run your client class in debug mode. The debugger will stop code execution when it reaches the breakpoint. Figure 5 shows the Application Developer debug perspective, with execution halted on the breakpoint. You can use views in the debug perspective to view the call stack, examine values of variables, and inspect sections of code.
    Figure 5. Debugging the createManagedConnection method
    Debugging the createManagedConnection method

Testing and debugging in a managed environment

Testing and debugging in a managed setting is only slightly more complicated than in a non-managed environment. In a managed setting, the resource adapter is deployed to an application server. Calls to the adapter take place inside the Enterprise JavaBeans (EJB) container. To set up a managed test case, complete the following high-level steps:

  1. Create a new EJB project.
  2. Create a new EJB that will act as a client to your resource adapter.
  3. Set breakpoints in the adapter code.
  4. Create the UTE server instance that will be used for debugging.
  5. Deploy the managed connection factory and test application.
  6. Start the server instance hosting the EJB in debug mode.
  7. Invoke Universal Test Client to make calls to the EJB.

In this, you'll reuse basically the same CCI code as in the non-managed case, but this time the code will be executed by an EJB, and the managed connection factory will be bound in JNDI space.

Creating an EJB tester

The first step in creating a new EJB project is to switch to the J2EE perspective.

  1. Select Window > Open Perspective > J2EE from the top-level menu. In the J2EE Hierarchy view, locate and select the folder EJB Modules.
  2. Right-click on the folder and select New > EJB Project from the pop-up menu. In the EJB Project Creation wizard, select the default for EJB level (2.0) and click Next. Enter MGDTest for the Project name, and accept all other defaults for the project location and the Enterprise Application to which this project will belong (DefaultEAR).
  3. Click Finish. Under the EJB Modules branch in the J2EE Hierarchy view, a new EJB module named MGDTest will appear.

Now that you have an EJB project, you need to create an EJB that can be used for testing your adapter code.

  1. Switch to the J2EE Navigator view, and browse the MGDTest project to find the ejbModule folder.
  2. Select this folder and right-click. Select New > Package from the pop-up menu.
  3. In the New Java Package wizard, name the new package com.managedtest. Click Finish to create this package. Switch back to the J2EE Hierarchy view. Select the MGDTest EJB module and click the right mouse button.
  4. Select New > Enterprise Bean from the pop-up menu. Click Next in the Enterprise Bean Creation dialog. In the next Enterprise Bean Creation wizard panel, you can choose to create your bean as a stateless session bean.

    In real-world applications, you can invoke calls to the resource adapter from stateful session beans and BMP entity beans as well. The approach you choose depends on overall application design, but for the purposes of testing the resource adapter, stateless session beans are the simplest choice. Call your new session bean ManagedTester by entering this in the Bean name field.

  5. Accept the defaults for all other choices, making sure MGDTest is the host project and com.managedtest is the target package.
  6. Once you select Finish, the wizard generates the bean class and the home and remote interfaces.
  7. Add the cciBlackBox project to this new EJB project classpath by selecting it in the Properties Projects tab.

To test your adapter, you need to define a method on your EJB that can be invoked by an EJB client. To create a test method, you can:

  1. Open the bean implementation class ManagedTesterBean.java by double-clicking it in the J2EE Hierarchy view. Use the Java editor to code the implementation. Listing 7 below shows one sample test method implementation.
  2. Once the method implementation compiles, don't forget to add the method signature to the remote interface definition ManagedTesterBean.java by opening the remote interface Java file in the Java editor and copying the method signature into it.

Your managed tester EJB implementation is now complete.

Listing 7. Sample EJB method for testing the adapter in a managed setting

package com.managedtest;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.resource.cci.*;
import com.sun.connector.cciblackbox.*;

...
public String getPrice(String itemNumer)
	{
		String price = null;
		
		try
		{
			// Look-up a connection factory instance
			Context nc = new InitialContext();
			
			// Create and configure a managed connection 
                  // factory instance Properties were set when 
                  // managed connection factory was deployed
			ConnectionFactory cf  = 
                       (ConnectionFactory)nc.lookup("eis/cciblackbox");
		
			// No need to pass in userid and password in
                  // CciConnectionSpec call.  These values will
                  // be picked up from the JAAS entry
			// defined for the connection factory.			 
                  CciConnectionSpec cspec = new CciConnectionSpec();
			CciInteractionSpec ispec = new 
			   CciInteractionSpec();
			ispec.setFunctionName("GETPARTPRICE");
			
			// Connect to the EIS (...in our case RDBMS)
			Connection cx = cf.getConnection(cspec);
			
		  // Execute the stored procedure
		  Interaction ix = cx.createInteraction();
		  IndexedRecord input = new CciIndexedRecord();
		  IndexedRecord output = new CciIndexedRecord();
		  input.add(0, itemNumer);		
		  output = (IndexedRecord) ix.execute(ispec, input);
		  price = (output.get(0)).toString();
			
		}
		catch(Exception e)
		{
			System.out.println(e.getMessage());
			e.printStackTrace(System.out);
		}
		
		return price;
		
	}    

To use container managed sign-on, the deployment descriptor of the calling EJB must have a resource-ref element with a <res-auth>Container</res-auth> subelement set. This tells the application server that it should provide security information to the resource rather than the application. To set this up:

  1. Within the MGDTesterEJB project, find the ejb-jar.xml file (under the META-INF folder) and double-click on it to open the EJB Deployment Descriptor editor.
  2. Select the References tab in the editor.
  3. Highlight the ManagedTester EJB. Click Add.
  4. In the Add Reference dialog, as shown in Figure 6, select the EJB resource reference dialog radio button and click Next.
    Figure 6. Adding resource references to an EJB deployment descriptor
    Adding resource references to an EJB deployment descriptor
  5. As shown in Figure 7 below, type CciBlackBox in the Name field. Select the javax.resource.cci.ConnectionFactory option from the drop-down list in the Type field. Select Container in the Authentication field. Leave Shareable as the Sharing scope value, indicating that the connections to the EIS can be shared. Finally, type JCA Resource Reference in the Description field and click Finish to create the resource reference.
    Figure 7. Adding EJB resource references
    Adding EJB resource references
  6. Highlight the new ResourceRef cciblackbox resource reference and type eis/cciblackbox in the JNDI name field under the WebSphere Bindings section. Save these changes and close the EJB editor.

Setting up the UTE server instance

To debug in a managed setting, you first need to create a UTE server instance and configuration that will host your resource adapter. To do this:

  1. Switch to the server perspective by selecting Window > Perspective > Server.
  2. Select the Servers folder in the Server Configuration view. Click the right mouse button to bring up a pop-up menu.
  3. Select New > Server and Server Configuration.
  4. As shown in Figure 8, in the Create New Server and Server Configuration Wizard, type TestServer in the Server name control.
  5. Select WebSphere Version 5.0 > Test Environment from the list.
    Figure 8. Creating a new server instance and configuration
    Creating a new server instance and configuration

Because the CciBlackBox adapter will be interacting with a relational database system, you should address the security aspect of the adapter. Here's how to set up the JAAS configuration.

  1. In the testServer configuration panel, highlight the Security tab.
  2. Under the JAAS Authentication Entries section, click Add.
  3. As shown in Figure 9, choose and type a name in the Alias field. (We used partUser.)
  4. Type a valid database user ID and password in the User ID and Password fields.
  5. Click OK to create this new JAAS entry.
    Figure 9. Entering a JAAS authentication entry
    Entering a JAAS authentication entry

Now, you need to deploy a managed connection factory to the test server. Use the following steps:

  1. While still in the Server administration configuration panel, click the J2C tab to view this panel.
  2. Scroll down to the Server Settings section.
  3. The Add button should be active to the right of the J2C Resource Adapters section. Click Add. Since you should only have one adapter imported in your workspace, you should see the CciBlackBox adapter in the Resource Adapter Name field of the Create Resource Adapter dialog (and some other non-editable info on the dialog).
  4. Select the CciBlackBox adapter by clicking OK in the Create Resource Adapter dialog.
  5. Highlight the CciBlackBox adapter in the J2C Resource Adapters list. Click Add to the right of the J2C Connection Factories section.
  6. As shown in Figure 10, type CciBlackBox in the Name field and eis/cciblackbox in the JNDI name field. Under the Container-managed authentication alias field, select partUser from the drop-down selection box. Accept all other default values for the other fields and click OK. This defines the container managed authentication that will be used when your EJB establishes a connection to the adapter, since you earlier defined "container" authentication in your EJB ResourceReference.
    Figure 10. Setting managed connection factory properties
    Setting managed connection factory properties
  7. Notice that the Resource Properties section, shown in Figure 11, is populated after creating the J2C connection factory. There are two default entries for this adapter; one specifies the database connection string, and one specifies the new JdbcDriver property. These values are initially derived from the ra.xml file you modified earlier.
    Figure 11. Configuring server settings
    Configuring server settings
  8. Save and close the TestServer configuration.

Before moving on, start up the test application server and verify that your JCA adapter is recognized and binds correctly. It is good time to do that now, so that you can isolate any potential problems while you have a very clean application server setup -- you've only added a JAAS entry and this adapter.

  1. Highlight TestServer under the Servers view of the Server perspective.
  2. As shown in Figure 12, right-click and select Debug to start up the application server in debug mode. (Select Start to start in regular mode.)
    Figure 12. Starting the server instance in debug mode
    Starting the server instance in debug mode
  3. Once the application server begins to initialize, the Servers view in the Server perspective switches to the Console view and systemOut messages associated with the application startup process begin to appear in this window. You should see a message similar to the following, indicating that the application server performed the CciBlackBox /jndi binding successfully.
    [4/1/03 15:41:29:764 EST] 19bda462 ResourceMgrIm I WSVR0049I: Binding CciBlackBox as eis/cciblackbox

If you get error messages, see the Application Developer and WebSphere Application Server online help to try to resolve the problem.


Using Universal Test Client for managed environment debugging

You are now ready to test the adapter in a managed environment. Generate the deploy code by highlighting the MGDTest project from either the Server or J2EE perspective and selecting Generate > Deploy and RMIC Code, ensuring the ManagedTester EJB is checked in the Generate Deploy and RMIC Code dialog, and clicking Finish.

Then deploy the application by right-clicking on the TestServer configuration in the Server perspective, and selecting Add > DefaultEAR from the pop-up menu. Restart the server if it is already running.

The only step left is to invoke the test method on your EJB. Application Developer provides Universal Test Client, a very handy feature, for precisely this purpose. You can use UTC to unit test any EJB and browse the JNDI namespace. To launch UTC once the server is started, select the server in the Servers view, right-click, and select Run Universal Test Client from the pop-up menu. Figure 13 shows the UTC home page.


Figure 13. UTC home page
UTC home page

Select the JNDI Explorer link on the UTC homepage. You will see a panel showing different objects bound in the JNDI space. Browse the links to find your test EJB home, and select that link. You will see a panel that shows methods available on your home interface. Select the create() method. Use the UTC UI to create an instance of the ManagedTester EJB.

Figure 24 shows the UTC UI that lets you enter parameters to your test method and execute the test method.


Figure 24. Entering parameters for the test method using the UTC
Entering parameters for the test method using the UTC

When you execute the test method on the EJB, the debugger will stop when it hits the breakpoint inside the createManagedConnection method of the managed connection factory. The debugger will locate and display the source when the breakpoint is reached. As with the non-managed case, you can observe the call stack, variable values, and code snippets.

It is interesting to examine options provided by the Application Developer server configuration editor and the Deployment Descriptor Editor. (The latter can be opened by selecting an EJB in the J2EE Hierarchy view and double-clicking on it). Using these tools, you can turn server security on and off, change transactional characteristics of the test bean, and change security identity assigned to the EJB by the server. You can use these features in conjunction with the debugger and the UTC to examine the workings of your connection management, transaction management, and security contract implementations.

Depending on the hardware platform used, there might be some sluggishness during the initialization of the test server when started in debug mode. The actual debug session with the EJB may also appear somewhat delayed in response. To avoid such performance problems, the recommended hardware configuration for the machine hosting Application Developer is a Pentium III 500 MHz or higher processor, and 786 MB of RAM. If your development platform is lower on memory, you may be able to reduce performance problems by adjusting the heap memory requirements for Application Developer and the test server. You can make adjustments to the maximum heap size of either JVM process by using the vmargs -Xmx option, which can help prevent excessive memory use from the JVM and reduce memory contention (and resulting swapping) with the OS. See the Application Developer online help for more details.

If running the test server in debug mode still seems too slow on a less than optimally configured platform, using temporary trace statements, which would show up in the Application Developer console view, with the application server running in non-debug may serve as a reasonable alternative. Debugging in a non-managed environment provides another efficient alternative to running the UTE test server in debug mode.


Deploying the resource adapter to production

To deploy the resource adapter to the production server, you need to take two high-level steps:

  1. Export the connector project to a RAR file.
  2. Deploy the RAR file in the WebSphere Application Server used for production.

The rest of this section explains these two steps in more detail.

Exporting to a RAR file

To export your adapter to a RAR file, you need to:

  1. Select the CciBlackBox project in the Package Explorer view.
  2. Select File > Export from the top-level menu.
  3. Choose RAR file in the Export dialog that appears.
  4. Select a convenient directory in the Connector Export dialog. Click Finish.

You are now ready to deploy your adapter to the production server.

Setting up JAAS security

Before installing the resource adapter, you need to create the JAAS security entry. Connect to the production WebSphere Application Server with the administrative console, and use the following steps to complete the process.

  1. Select Security > JAAS Configuration > J2C Authentication Data from the Navigation panel on the administrative console.
  2. Click New to create a new entry, as shown in Figure 15.
    Figure 15. Entering J2C authentication parameters
    Entering J2C authentication parameters
  3. As shown in Figure 16, type partUser in the Alias field, <userid> for User ID field, and password for the Password field. Click OK.
    Figure 16. J2C authentication entry values
    J2C authentication entry values

Importing the adapter

Now you can import your J2C (or JCA) adapter, using the following steps.

  1. Select Resource > Resource Adapters from the Navigation panel on the administrative console, shown in Figure 17.
    Figure 17. Resource adapters link in the WebSphere Application Server administration console
    Figure 25. Resource Adapters link in the WebSphere Application Server Administration Console
  2. Click Install RAR to add a new adapter, as shown in Figure 18 .
    Figure 18. Resource adapters dialog
    Resource adapters dialog
  3. In the Install RAR File panel, browse to the appropriate directory and select the CciBlackBox.rar file. Leave all other fields set to default. Click Next.
  4. In the Resource Adapters > New panel, type CciBlackBox in the Name field. Leave all of the other fields blank. Click OK to add the adapter to the application server.
  5. You should now see a Resource Adapters panel showing all of the adapters installed. Click CciBlackBox to go to a panel that lets you define a connection factory for this adapter.
  6. In the Resource Adapters > CciBlackBox configuration panel, scroll down to the bottom and click the J2C Connection Factories link, as shown in Figure 19.
    Figure 19. J2C Connection Factories selection
    J2C Connection Factories selection
  7. In the Resource Adapters > CciBlackBox > J2C Connection Factories panel, click New to create a new connection factory.
  8. In the Resource Adapters > CciBlackBox > J2C Connection Factories configuration panel, type CciBlackBox for the name field and eis/cciblackbox for the JNDI name field. Select <servername>/partUser for the Container-managed Authentication Alias field. Leave all other fields set to default values. Click OK.
  9. You will now be back in the Resource Adapters > CciBlackBox > J2C Connection Factories panel with CciBlackBox listed as a connection factory. Click the CciBlackBox link to review the current configuration for this connection factory.
  10. You will now, again, be in the configuration panel for the connection factory. However, now if you scroll to the bottom of the panel, as seen in Figure 20, under the Additional Properties section, there are links to configure or modify settings for the Connection Pool or Custom Properties. Click Custom Properties.
    Figure 20. J2C additional properties
    J2C additional properties
  11. In the Resource Adapters > CciBlackBox > Custom Properties panel, you will see the two property variables and their values that were specified in your ra.xml deployment descriptor file (ConnectionURL and JdbcDriver properties), shown in Figure 21. The application server automatically sets these up as configurable properties in this panel, making it very convenient to customize these values for different production systems. For instance, if you need to alter the ConnectionURL to point to another database, you can do that easily in this panel. You could also easily alter the JdbcDriver to use a driver for another database vendor (such as DB2).
    Figure 21. J2C custom properties
    J2C custom properties
  12. If you go back to the previous panel and then click the Connection Pool link, you can observe and, if desired, modify parameters associated with connection pooling for the JCA connections. Most of these parameters relate to the ManagedConnection object (or CciManagedConnection for this adapter). The settable fields are shown in Figure 22. Stay with the default settings for this sample.
    Figure 22. Connection pools
    Connection pools
  13. You can now click Save at the top of the current configuration panel (in Message(s) subpanel). Click Save in the next Save to Master Configuration subpanel that appears. Your adapter is now deployed and saved in your production environment. Any EJB that will be used to interface with the adapter, such as the one used in the managed environment testing, can be deployed to the application server using the normal process to install an enterprise application. Access to the resource adapter is now available.

Summary

WebSphere Studio Application Developer v.5.0 provides a convenient environment for JCA development. You can readily import existing resource adapter source, then add features, unit-test, and debug without leaving the comfort of WebSphere Studio Application Developer. Once development is complete, you can export the adapter to a RAR file and deploy it to the production server. JCA developers can use this tool to enhance their productivity and boost production schedules.


Resources

About the authors

Michael McMahon is an Advisory Software Engineer currently working as a scenario solution developer and tester in the WebSphere System House at IBM in Raleigh, North Carolina. He has previously worked in the IBM WebSphere Edge Server team on load balancing and video streaming technology, and on a mix of video and database projects prior to that. Contact Michael at mmcmaho@us.ibm.com.

Mikhail Genkin is a Technical Solution Designer working with the IBM WebSphere System House group at the IBM Toronto Software Development lab. His work involves conducting expert reviews of IBM and competitor tools for Java and Web service-based enterprise access. He advises several IBM development teams building WebSphere tools for J2EE, Web services, RDBMS and EIS access about the usability, performance, and interoperability aspects of their products. He has contributed to several releases of VisualAge for Java, Enterprise Edition; WebSphere Application Developer; and WebSphere Application Developer - Integration Edition.

Mikhail Genkin holds a bachelor's degree in Geophysics from Carleton University, Ottawa, Canada, and an M.Sc. in Earth Sciences from University of Ottawa. He is a Sun Certified Java Programmer, and an IBM Certified Developer Associate - IBM VisualAge for Java. You can contact him at genkin@ca.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Sample IT projects
ArticleID=10282
ArticleTitle=Build JCA-compliant resource adapters with WebSphere Studio Application Developer
publish-date=08012003
author1-email=mmcmaho@us.ibm.com
author1-email-cc=
author2-email=genkin@ca.ibm.com
author2-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).