![]() |
Sun ONE Connector Builder 2.0 Developer's Guide |
Customizing the Generated Resource AdapterThis module describes the following topics:
- Overview of Customizations
- Customizable Elements of Generated Resource Adapters
- General Approach to Customizing Sun ONE Connector Builder Resource Adapters
- Customizing the Resource Adapter
- Customizing the Resource Adapter's JIOs
Overview of Customizations
As generated, the resource adapter contains all of the Java code required to work with the container into which it is deployed. It also includes most of the Java code needed to work with the EIS API you have described to Sun ONE Connector Builder, while defining the EIS API, but you must provide certain required, EIS-dependent logic yourself. Further, you may choose to customize other parts of the adapter to add additional logic even though the adapter would work without those changes.
To customize a generated resource adapter correctly, you need to understand how Sun ONE Connector Builder-generated adapters are logically structured and how they support customization. Both the adapter's logical structure and your approach to customizing that adapter depend on the style of the API that the EIS provides.
Customizable Elements of Generated Resource Adapters
Each generated resource adapter includes Java classes and properties files that you can customize. This section explains the structure and organization of the Java classes and the purposes of the properties files.
There are two different but equally valid ways to organize the generated Java classes into logical categories. One way is to look at the class hierarchy among the classes. Another way is to consider the functional responsibilities of the classes - the purpose that each class serves. This section describes the generated classes from both points of view, then explains the naming conventions used for the generated classes. These different perspectives are important in the detailed descriptions of the customizations you can implement on the resource adapter classes.
Categorizing Generated Classes by Class Hierarchy
Each generated resource adapter includes some logic that is shared among all resource adapters, some logic that is generated based on your input, and some logic that you must implement yourself as customized Java code. To help simplify each resource adapter and to preserve your customizations, the Sun ONE Connector Builder organizes this logic into a three-level class hierarchy, as shown in "Three-level Resource Adapter Class Hierarchy". This figure shows the relationship among the classes in the three levels of the hierarchy and the packages that contain those classes for one example class: ICONConnection and its related subclasses in the COTS sample resource adapter. Similar relationships exist among all the classes in the CCI and SPI packages.
   Three-level Resource Adapter Class Hierarchy
![]()
Basically, level 1 classes contain logic that is common to all adapters. Level 2 classes contain logic that depends on the specifics of an adapter's definition. Level 3 classes provide places for you to customize the generated adapter.
Level 1 Classes
Level 1 classes include the Sun ONE Connector Builder's implementation of the interfaces that the J2EE Connector Architecture prescribes. The logic in these classes is the same for all adapters. 'These classes are provided in the iconadapter.jar file that is installed in <connector_builder_install_root>/lib directory.
The API documentation for the level 1 classes provides additional information about the level 1 classes. After installation, this API documentation is in the <connector_builder_install_root>/docs/api directory.
Level 2 Classes
The Sun ONE Connector Builder generates classes in level 2 using the information that you supply when you run the Wizard or modify a previously-defined resource adapter. These classes extend (are subclasses of) the level 1 classes. When you finish the Wizard or use the Generate pop-up menu action for a resource adapter, Connector Builder generates the classes in level 2 based on the adapter definition. So, while the level 1 classes contain logic that works for all resource adapters, the level 2 classes contain logic that is tailored specifically to one resource adapter.
Whenever you generate the resource adapter, any classes already in level 2 are replaced. Although you can view the contents of these files, you should not modify them. Any changes you make in the level 2 classes are overwritten with generated code the next time you generate the resource adapter.
Level 3 Classes
The level 3 classes, also generated by the Sun ONE Connector Builder and which inherit from their level 2 counterparts, are where you implement all mandatory, basic, and advanced customizations.
Because you may modify classes in level 3, the Sun ONE Connector Builder preserves your customizations when it regenerates the resource adapter. Refer to "Preserving Customizations" for more information on how the Sun ONE Connector Builder retains your customizations.
Note You must recompile and rebuild the resource adapter and redeploy it after you implement or change any customizations before the changes take effect.
Categorizing Generated Classes by Functional Responsibility
Quite apart from their inheritance structure, the Java classes also form groups of related functional responsibilities. There are three such groups:
- Classes for Invoking the EIS API
- Classes for Managing Connections, Transactions, and Security
- Java Interaction Object (JIO) Classes
Classes for Invoking the EIS API
Some generated classes are dedicated to invoking the EIS API methods. A brief review of how the J2EE Connector Architecture models the invocation of methods helps to explain this group of classes.
The J2EE Connector Architecture uses the idea of a Common Client Interface (CCI) as a model for invoking any EIS API method. Briefly, the CCI model includes these key elements related to method invocations:
- an InteractionSpec that represents a method in the EIS API;
- an input Record that holds all parameter values that must be passed into the method;
- an output Record that holds the return value, if any, from the method;
- an Interaction that represents a single invocation of a method in the EIS API.
An application that uses a CCI-compliant adapter obtains an instance of the InteractionSpec corresponding to the method it needs to invoke. It also obtains an instance of the input Record corresponding to that method's InteractionSpec and assigns the values in that Record to be passed as the input parameters to the EIS API method. The application also gets an instance of the output Record for the InteractionSpec. Finally the application creates a new Interaction representing the desired call of the method with the assigned input parameter values.
The application then executes that Interaction, passing the InteractionSpec and the input and output Records. This ultimately invokes the EIS API method, and the method's return value (if any) is made available via the output Record. The J2EE Connector Architecture describes several variations on this basic approach, but the roles and responsibilities of the classes are fundamentally the same in all variations.
With Sun ONE Connector Builder, the style of EIS API - specific vs. general-purpose - influences how you define the resource adapter and, in turn, which classes are generated and what they contain.
Generated EIS API Method Classes for a Specific EIS API
If the EIS API at hand is specific, then typically you should choose one or more methods from the EIS API when you define the resource adapter. For each method you select, the Sun ONE Connector Builder generates three classes:
- an InteractionSpec
- an input Record
- an output Record
All three classes are generated according to the details you provided using the Wizard or the IDE's contextual menus: the EIS API class and method names, the parameters it accepts, and any return value it provides.
Generated EIS API Method Classes for a General-purpose EIS API
On the other hand, if the EIS API is general-purpose you usually do not choose any method in the EIS API when you define the resource adapter. The generated adapter then contains a single general-purpose InteractionSpec and a RecordFactory. Without information about the methods you want to use - their names, input parameter names and types, and return value types - Sun ONE Connector Builder cannot generate the logic it can for a specific EIS API.
You need to customize these generated InteractionSpec and Record classes. Refer to the Installation and Getting Started Guide for more information on customizing these generated classes to work with general-purpose EIS APIs.
Classes for Managing Connections, Transactions, and Security
The second functional grouping of classes includes generated classes for managing connections, transactions, and security. These classes control how the adapter operates in its container, whereas the first group of classes deals with how the adapter interacts with the EIS API. The connector architecture dictates and illustrates how these classes are used in an application. In this respect, at least, these classes generated by Sun ONE Connector Builder are no different from the connection, managed connection, transaction, and similar classes in a resource adapter written by hand.
Java Interaction Object (JIO) Classes
A Java Interaction Object (JIO) provides additional convenience to the application developer over and above what the J2EE Connector Architecture prescribes for Interactions and InteractionSpecs. For each EIS API method you identify when you define the resource adapter, Sun ONE Connector Builder generates one JIO class. This class provides a streamlined way for an application to obtain a connection to the EIS, invoke the corresponding EIS API method, and even start a transaction automatically before invoking the method.
The JIO classes are discussed in more detail in "Customizing the Resource Adapter's JIOs".
Naming Conventions for Generated Classes
The Sun ONE Connector Builder provides default names for all the generated classes, although you can modify the defaults if you wish. The names for classes related to the EIS API methods are constructed from several values as listed in the table below. The left most column lists the Naming Element. The second column lists where it is used. The third column lists applicable COTS examples and the right column lists the applicable JDBC examples.
The following is the general naming pattern for the generated classes related to the EIS API methods:
[EIS API class name][EIS API method name][class usage]
For the single getCustomer method in the COTS example the Sun ONE Connector Builder generates classes named:
COTSAPIGetCustomerISpec
COTSAPIGetCustomerInputRecord
COTSAPIGetCustomerOutputRecord
derived as the table describes.
For general-purpose adapters in which you select no specific EIS API methods, the pattern is this:
[adapter logical name][class usage]
For the DBMS example for JDBC, the Sun ONE Connector Builder generates classes named
DBMSISpec
DBMSRecordFactory
derived as shown in the Names for Classes Related to Connections, Transactions, and Security table below.
This is the general form for the names of these classes:
[adapter logical name][interface name]
For example, the class name for the COTS adapter's implementation of the javax.resource.spi.ManagedConnection interface is
COTSManagedConnection.
The table summarizes how the names are assigned for the generated classes related to managing connections, transactions, and security. The left most column lists the Naming Element. The second column lists where it is used. The third column lists applicable COTS examples and the right column lists the applicable JDBC examples.
Generated Properties Files
In addition to Java classes, Sun ONE Connector Builder also creates several Java properties files. These files influence the run time behavior of the adapter.
The following three files are generated into the src subdirectory in the adapter base directory that you specified to the Wizard:
- <adapterLogicalName>RAMD.properties
- <adapterLogicalName>log.properties
- <adapterLogicalName>.properties
<adapterLogicalName>RAMD.properties
This file contains property settings for the four values available from ResourceAdapterMetaData:
- adapterShortDescription
- adapterVendorName
- adapterVersion
- adapterName
The "<adapterLogicalName>RAMD.properties code example " shows the file generated for the DBMS sample adapter
.
You provide this information to the Wizard when you define the adapter, and the values you supply are placed into the generated file. The J2EE CA explains that the ResourceAdapterMetaData class describes the adapter itself, not the instance of the EIS that the adapter might be connected to at any given moment.
This properties file is generated by Sun ONE Connector Builder so you can localize it to support an international user base. When the application or an administration tool requests resource adapter metadata from an Sun ONE Connector Builder resource adapter, the adapter retrieves the information from this properties file or a suitably localized version of it. This allows you to localize the properties file for any number of locales, package the resource adapter once with all the localizations, and then deploy the same adapter unchanged in any of the locales.
<adapterLogicalName>log.properties
The resource adapter uses this file to control its logging. The generated file (see the "<adapterLogicalName>log.properties code example ") contains default logging settings, and you can adjust these as you see fit to alter the default logging behavior. Refer to "Administration and Monitoring of the Generated Resource Adapter" for more information about logging.
The "<adapterLogicalName>log.properties code example " shows the file generated for the DBMS sample adapter.
<adapterLogicalName>.properties
This following code example contains only comments when generated, as shown in the "<adapterLogicalName>.properties" code example. This file serves as the resource bundle for all message strings that are used in your customized code. You can place any messages that your resource adapter will use at run-time into this file.
Note The generated adapter does not use this file for its own internal messages.
General Approach to Customizing Sun ONE Connector Builder Resource Adapters
This section introduces the general approach you should take as you customize a generated resource adapter, including these topics:
Customizing the Properties Files
You can customize as many or as few of the generated properties files as you wish. Depending on the specific properties file, some changes may take affect even for an already-running resource adapter. Changes to other properties files might not become effective until some software component is restarted
<adapterLogicalName>log.properties
The <adapterLogicalName>log.properties file is used at run-time to control logging. As such, you need to customize this file to alter the resource adapter's logging behavior. This file is not used as a resource bundle for retrieving internationalized or localized messages.
<adapterLogicalName>RAMD.properties
You can create additional variants of this file following the following the standard Java file naming convention for localized property files.The Java Developer's Connection contains several articles at http://developer.java.sun.com/developer/technicalArticles/Intl/ describing how to localize resource bundles. For example, you can create a French-language variant named <adapterLogicalName>RAMD_fr.properties, or a French-Canadian version as <adapterLogicalName>RAMD_fr_CA.properties. You can provide the appropriate translations for the property values in the variant files and package them with your adapter. At run-time, the generated code that furnishes the ResourceAdapterMetaData uses the current run-time locale in locating the applicable properties file variant and loads the values from that file.
<adapterLogicalName>.properties
The file is empty except for some comments generated by the Sun ONE Connector Builder. This file serves as the resource bundle for all message strings used in your customized code. If your customized Java code in the resource adapter uses any messages, you can define those messages in this file for internationalization.
As with <adapterLogicalName>RAMD.properties, you can create other variants of this file to localize its content.
General Approach to Customizing Java Classes
This section describes these aspects of customizing the generated Java classes:
Later sections of this module xplain the specific customizations available to you in detail.
Preserving Customizations
Note Always implement your customizations in the level 3 classes.
Your customizations are preserved, even if you generate the resource adapter more than once. The classes in level 2 of the adapter are overwritten each time you generate the resource adapter. These classes depend on information you provide in the resource adapter definition, and when you generate the adapter, Sun ONE Connector Builder rewrites the level 2 classes so they reflect the current adapter definition.
You may customize some of the files that the Sun ONE Connector Builder generates, but not all of them. Non-customizable classes are recreated every time you generate the resource adapter. The Connector Builder overwrites any previously-generated files of the same name in the same directory. The cci and spi level two classes fall into this category. You should not customize these classes because the customizations will be lost the next time you generate the resource adapter.
In contrast, there are other classes that are specifically intended for you to customize. Once these classes are generated, the Connector Builder preserves them and any customizations you have made to them. Sometimes the previously-generated classes are untouched by regeneration; sometimes the previous files must be replaced. It is important for you to understand how the Connector Builder makes these decisions about customizable files. Keep in mind that the files of interest here are the customizable ones, such as the classes in level 3 of the resource adapter.
In defining and modifying the resource adapter definition, you affect a number of characteristics of the adapter as a whole - for instance, whether or not transactions are supported. When the Connector Builder generates files, it uses these characteristics to decide what to name the file, what code should be written into the file, and in some cases whether the file should be present at all in the generated resource adapter. Each generated file depends on a different group of characteristics.
When you regenerate the adapter, the Connector Builder checks the adapter characteristics that influence each type of file to decide how to handle a previous version of the file. What the Connector Generator does next depends on what changes you have made to the adapter definition since the most recent generation.
If the characteristics that affect a given file have not changed since the previous generation, then the Connector Builder does not generate that file again. Instead, it leaves the previously-generated file in-place, unaltered. This includes any customizations you implemented in that file.
On the other hand, if the adapter characteristics associated with a particular type of file have changed, then the Sun ONE Connector Builder renames the previously-generated file of that name and then generate the file again according to the new set of adapter characteristics. Sometimes, this means that the file is not regenerated at all. For example, if you initially selected support for local transactions and generated the adapter but then removed transaction support and regenerated, you will find that the previously-generated level 3 LocalTransaction class has been renamed but there is no new LocalTransaction class.
When the Connector Builder renames previously-generated files, it appends .bak to the original file name. If a previous back-up copy of the file with that name already exists, then the Connector Builder uses the suffixes .bak1, .bak2, and so forth. You can copy your previous customizations from these backed-up files into the newly-generated files, as applicable.
You may notice a ".generated" file - a file with an empty name and the file type "generated" - in each directory that contains customizable files. You should not delete, rename, or edit any .generated files. The Connector Builder uses these files to record the adapter characteristics that influence each of the generated classes.
Customization Points and Categories of Customization
There are three categories of customizations you can implement in the generated resource adapter:
- Mandatory Customizations
- Basic Customizations (optional)
- Advanced Customizations (optional)
You must implement mandatory customizations or the resource adapter will not work correctly. For example, you must provide the logic required to establish a physical connection to the EIS.
Basic customizations are optional but are common enough for Sun ONE Connector Builder to simplify the process of implementing them.
Advanced customizations also are optional. These are relatively uncommon.
The Sun ONE Connector Builder provides customization points for mandatory and basic customizations. Customization points are specific methods in particular classes for holding custom, EIS-dependent logic. The customization points in Sun ONE Connector Builder-generated resource adapters are explained in detail later in this module.
Mandatory Customizations
The method signature for each mandatory customization point appears in the generated source code in a level 3 class, but in commented form. At either level 1 or 2, the same method is declared as abstract, requiring that a subclass implement the method. If you do not uncomment the method signature in the level 3 class, the Java compiler reports an error, indicating that the level 3 class should be declared abstract because it does not implement the method. Note that you should provide a valid implementation of the customization point and not merely uncomment the signature.
Basic Customizations
Basic customization points - for common, optional customizations - appear as concrete methods in the class hierarchy. Some have default implementations and others are empty. These methods compile correctly as generated, without change, so you will need to note which basic customizations are suitable for your resource adapter.
Advanced Customizations
In contrast, advanced customizations do not have explicit customization points. Instead, you can override or modify the methods in the generated classes to implement your advanced customizations.
If you implement an advanced customization by overriding a level 1 or 2 method at level 3, realize that the level 3 method may prevent important logic at level 1 or 2 from running. In general, you should read the level 2 implementation of the method you want to override and make sure you invoke the level 2 method from your level 3 advanced customization or reproduce the level 2 logic in your level 3 method.
Customizing the Resource Adapter
This section discusses the customization points in the generated resource adapter. The following topics are described:
Mandatory Customization Points
This section describes the mandatory customization points:
- Mandatory Customizations Related to EIS API Method Invocation
- Mandatory Customizations Related to Connections, Transactions, and Security
Mandatory Customizations Related to EIS API Method Invocation
There are no mandatory customization points in this category for a resource adapter that uses a specific EIS API. On the other hand, there are mandatory customization points for a resource adapter that invokes a general-purpose EIS API.
Different general-purpose EIS APIs may require different customizations. Generally, the level 3 Interaction.execute method uses the functionName property of the general-purpose InteractionSpec to find out what specific work to accomplish in the EIS. This may also determine how the Interaction should treat input parameters before calling the EIS API method and how it should treat any output parameter afterward. The Interaction.execute method typically invokes a general-purpose EIS API "execute" or "perform" method to trigger the work in the EIS.
Further, the RecordFactory may need to be customized so that it can provide the application the correct implementations of the Record interface.
The sample DBMS resource adapter included with Sun ONE Connector Builder provides good examples of these techniques. Refer to the Sun ONE Connector Builder Installation and Getting Started Guide for more information on customizing these generated classes to work with general-purpose EIS APIs.
Mandatory Customizations Related to Connections, Transactions, and Security
The mandatory customization points for classes that manage connections, transactions, and security appear in the classes that implement these J2EE CA interfaces are:
spi.LocalTransaction
(customization required only if you specified that the adapter should support transactions)
void doBegin()
Whatever logic is required to start a transaction in the EIS API. If the EIS API returns a transaction identifier of some sort, you may need to add a field to the class to hold the identifier for use by the other methods.
The code example below provides an example code fragment for the mandatory customization point doBegin:
In the "Example Code Fragments For Mandatory Customization Point doBegin" code example, the code obtains the actual JDBC connection from the customized spi.ManagedConnection class. The code then turns off auto-commit for that JDBC connection - but only for the duration of the transaction, as the examples for doRollback and doCommit show. If any errors occur along the way, the code throws a ResourceException describing the problem and linking to the actual exception thrown by the EIS - the JDBC connection in this case.
void doCommit()
Whatever logic is required to commit a transaction in the EIS API.
The code example below provides an example code fragment for the mandatory customization point doCommit:
This method delegates the work of committing the transaction to the JDBCconnection. In fact, if the EIS API your adapter works with support transactions, transaction-related customizations probably delegate this work to the EIS API as well. Note that the JDBC connection is set back to auto-commit, because this is the default behavior for JDBC connections. This leaves the connection ready for its default behavior if the application next uses database manipulation that does not explicitly use an spi.LocalTransaction. Again, notice the use of ResourceException in case anything goes wrong in committing the transaction.
void doRollback()
Whatever logic is required to rollback a transaction in the EIS API.
The "Example Code Fragment For Mandatory Customization Point doRollback"example provides sample code for the mandatory customization point doRollback:
This logic is identical to doCommit's except that the JDBC connection is told to roll back the transaction rather than commit it. The default auto-commit behavior of the JDBC connection is restored and a ResourceException is thrown if any errors occur.
spi.ManagedConnection
You need to customize methods that create a physical connection to the EIS as well as methods that clean-up and destroy a physical connection when it is no longer needed.
Methods for Creating a Physical Connection
Part of the resource adapter definition indicates what kind of authentication the adapter supports. You can specify that the adapter supports basic password authentication, generic authentication, neither, or both.
Depending on which authentication mechanisms your adapter supports, you need to provide one, two, or three implementations for the createPhysicalConnection method.
The "Authentication Mechanisms Signatures" table below shows which signatures you must implement depending on the authentication mechanisms your adapter supports. The left most column lists the Signature. The right most column lists the Authentication Supported. The types of Authentications Supported are displayed in four different columns; the left most column being basic, the following column, generic, the following column Neither and the right most column both.
Object createPhysicalConnection(ConnectionRequestInfo) #1
Uses whatever logic is required to create a physical connection to the EIS, using the ConnectionRequestInfo contents. The generated ConnectionRequestInfo class conveys client-related property values as you defined them using the Wizard when you defined the adapter.
To implement the createPhysicalConnection method, return an object that represents the physical connection to the EIS. The generated InteractionSpec classes look up and use this object as a connection-type parameter in EIS API method calls. The following code example displays the code for Object createPhysicalConnection(ConnectionRequestInfo) #1:
This variant of createPhysicalConnection accepts an instance of ConnectionRequestInfo. ConnectionRequstInfo contains adapter-specific information that may be useful in constructing or allocating a physical connection to the EIS API. The code must cast the parameter to the adapter's own implementation of javax.resource.spi.ConnectionRequestInfo to obtain the adapter-specific information from the application: user and password for the user on whose behalf the connection should be established. Any adapter's implementation of this method needs to cast the argument similarly.
All managed connections created by a single managed connection factory connect to the same database, using the connection URL recorded by the managed connection factory. That connection URL, the username, and the password are then used to create a new JDBC connection. As usual, exceptions are caught and wrapped by a javax.resource.ResourceException.
Object createPhysicalConnection(String, char[]) #2
Uses whatever logic is required to create a physical connection to the EIS, using the username and password values passed as arguments. The following code example displays the code for Object createPhysicalConnection(String, char[]) #2.
Here, the user and password are provided as separate parameters to the method. The rest of the logic is very similar to the first variant of the method. Note that, because the signature specifies that the password parameter is a char array, that array is converted into a String before being passed to the DBMS driver's getConnection method.
Object createPhysicalConnection(GenericCredential) #3
Uses whatever logic is required to create a physical connection to the EIS, using the GenericCredential contents. Similar work takes place in this variant of createPhysicalConnection. The main difference is that you need to get the required authentication information from the GenericCredential and pass these values to establish a connection without specific user and password settings.
Methods for Cleaning Up and Destroying a Physical Connection
In addition to implementing methods that create new physical connections, you need to provide a method for reusing and destroying them as well. The doDestroy method is invoked when the container in which the adapter is running no longer needs that physical connection and does not reuse it. You need to implement doDestroy, typically using the EIS API to end the specific physical link with the EIS.
Creating new physical connections to the EIS is often costly and slow. To minimize this cost, the container may try to reuse physical connections. To support this type of connection pooling, you implement the doAdditionalCleanup method. In this method you place any logic required to prepare a physical connection for reuse. This logic should account for the fact that the physical connection has been used previously on behalf of one client but is about to be used on behalf of another client.
void doDestroy()
Whatever logic is required to end this managed connection's physical connection to the EIS. Your logic can use this.getEISConnection() to retrieve the object returned from createConnection if it needs access to it.
void doAdditionalCleanup()
Uses whatever logic is required to clear any context related to a particular client's use of the physical connection so the connection can be used - without being destroyed - by another client.
spi.ManagedConnectionFactory
boolean matchConnection(ICONManagedConnection, Subject, ICONConnectionRequestInfo)
Returns true or false, depending on whether the ICONManagedConnection instance should be used to satisfy the connection request for the specified Subject considering the specified ICONConnectionRequestInfo contents. The customized code should use whatever of the supplied information is relevant to make the decision, respecting any requirements and restrictions that might be implied by the EIS. The following code example displays the code for ManagedConnectionFactory.matchConnection from the DBMS sample adapter.
Basic Customization Points
This section describes the basic customization points for the Connector Builder generated resource adapter. The basic customizations are described as they are related to either one of the following:
- Basic Customizations Related to EIS API Method Invocation
- Basic Customizations Related to Connections, Transactions, and Security
Basic Customizations Related to EIS API Method Invocation
The following lists the basic customization points for invoking EIS API methods:
cci.Interaction
The methods in an EIS API may throw exceptions when they encounter errors. Some of these errors might be considered "normal" during routine operation, such as failing to find a requested customer given a customer ID, for example. Often, the same connection to the EIS can be used successfully to call other methods. In contrast, other errors might indicate that there is a problem with the connection to the EIS itself, such as a network failure or the EIS being stopped. After this type of error occurs on a connection, that connection may be unusable for further requests to the EIS.
The J2EE Connector Architecture specification explains that the resource adapter should report such connection errors to the container. The generated resource adapter can do this automatically, but you need to provide the logic to determine if an exception represents a connection error or not.
boolean checkForConnectionError(Exception exc)
If your EIS API throws exceptions that represent connection errors, you should implement the checkForConnectionError method on the level 3 generated Interaction class. Your logic should inspect the type of the exception and, perhaps, the message associated with it, to determine whether the exception indicates that the connection will no longer work. Return true, if the error affects the connection (and therefore the connection cannot be used again), and return false, if the error does not affect the connection's future usage.
The generated InteractionSpec execute methods automatically invoke this method to decide whether to report a connection failure to the container or not.
Basic Customizations Related to Connections, Transactions, and Security
The following lists the basic customization points for classes for managing connections, transactions, and security.
spi.ManagedConnection
During its operation, the resource adapter needs to create new instances of certain classes. As generated, the resource adapter contains default logic for performing these instantiations that work for many adapters. If you need to change any of this logic, you can do so by implementing the following methods on the generated level three ManagedConnection class. Note that the only time you should need to override these methods at level three is if you want to add a constructor or change a constructor's signature. If you want to change only what happens inside the new object's constructor, you can customize the constructor for the class rather than the corresponding "instantiate" method.
Object getInstance(Class)
When you define the EIS API to Sun ONE Connector Builder, you identify the EIS API class or interface on which the method is defined. To invoke an EIS API method, the generated InteractionSpec classes must obtain an instance of the correct class type on which they can invoke the method. Customize this getInstance method to return an instance of the requested class type, suitable for use in invoking an EIS API method. You have complete flexibility in deciding what instance to return as long as it is of the requested class type and meets any requirements that the EIS API itself imposes.
The generated ManagedConnection class includes a default implementation of getInstance, as shown in the "ManagedConnection.getInstance" code example. This implementation uses the Class.newInstance method to create a new object of the requested class type. For many resource adapters, this may be sufficient. The specific details of your EIS API may require you to modify the default implementation. When you select EIS API methods, you can choose an interface in the EIS API as opposed to (or in addition to) a class. In that case, you must customize getInstance to detect if the requested class type is an interface. If so, then getInstance must provide an instance of a class that implements the requested interface, using logic appropriate to the particular EIS. Note that if you do not customize getInstance, an invocation of getInstance with an interface type throws an exception at run-time.
The DBMS adapter uses the default implementation of getInstance. In fact, the DBMS adapter does not use getInstance because no EIS API methods are invoked from generated InteractionSpec classes. That is where getInstance is invoked from.
ICONLocalTransaction instantiateLocalTransaction(ICONManagedConnection mc, boolean sendEvents)
The instantiateLocalTransaction method is called whenever the application or the container needs a LocalTransaction instance. The implementation of this method in its super class base.spi.ManagedConnectionBase creates a new instance of the adapter's local transaction and returns it.
You should override this method and provide your implementation if your adapter supports local or XA transactions and if you need to alter this default logic in any way.
javax.transaction.xa.XAResource instantiateXAResource()
Returns an object that implements the
interface. This method is invoked whenever the application or the container needs an XA transaction instance.
Connector Builder generates the sample implementation code for this method within comments. You need to provide a proper implementation for this method if your adapter supports XA transactions.
protected ICONConnection instantiateConnection(ICONManagedConnection mc)
When the client application requests a new Connection, the resource adapter uses this method to create that new object. The implementation of this method is generated in its super class base.spi.ManagedConnectionBase. The following is the generated implementation from the COTS sample resource adapter in the base.spi.COTSManagedConnectionBase.java
return new com.sun.appinteg.samples.cots.cci.COTSConnection(mc);
You should override this method and provide your implementation if you need to alter this default logic in any way. In your implementation, make sure that you instantiate the level three Connection class.
public javax.resource.spi.ManagedConnectionMetaData instantiateManagedConnectionMetaData()
The default implementation of this method is generated in its super class base.spi.ManagedConnectionBase. The following code example is the implementation from the sample COTS adapter base.spi.COTSManagedConnectionBase.java:
Often, the EIS API will provide methods for interrogating the EIS to obtain its name, version, and other information at run-time. If so, you need to override this method and provide implementation to use the dynamic information in preparing the metadata to be returned to the caller. Alternatively, you can customize the generated ManagedConnectionMetaData class.
public PasswordCredential preparePasswordCredential(ConnectionRequestInfo requestInfo)
This optional performance optimization customization can be added, only when the resource adapter supports Password credential security mechanism. Default implementation is not generated.
The security credentials required to obtain the connection can be provided either by the application using ConnectionSpec or by the container using Subject. Additionally, the container can try to reauthenticate a ManagedConnection by passing Subject or ConnectionRequestInfo. Because of these different approaches, the ManagedConnection keeps the credential information in a normative way (as PasswordCredentail) in the ManagedConnection instance. If a ConnectionRequestInfo is used to acquire the connection, this method is called to convert it to PasswordCredential.
The implementation of this method should return a valid PasswordCredential created out of the ConnectionRequestInfo.
public GenericCredential prepareGenericCredential(ConnectionRequestInfo requestInfo)
This optional performance optimization customization can be added, only when the resource adapter supports the Generic credential based security mechanism. Default implementation is not generated.
The security credentials required to obtain the connection can be provided either by the application using ConnectionSpec or by the container using Subject. Additionally, the container can try to reauthenticate a ManagedConnection by passing Subject or ConnectionRequestInfo. Because of these different approaches, the ManagedConnection keeps the credential information in a normative way (as GenericCredentail) in the ManagedConnection instance. If a ConnectionRequestInfo is used to acquire the connection, this method is used to convert it to GenericCredential.
The implementation of this method should return a valid GenericCredential created out of the ConnectionRequestInfo.
spi.ManagedConnectionFactory
ICONManagedConnection instantiateManagedConnection(ICONManagedConnectionFactory mcf, ConnectionRequestInfo cri)
ICONManagedConnection instantiateManagedConnection(ICONManagedConnectionFactory mcf, PasswordCredential pc)
ICONManagedConnection instantiateManagedConnection(ICONManagedConnectionFactory mcf, GenericCredential gc)
The generated level two classes provide default implementations for these three methods. They simply instantiate the generated ManagedConnection class passing the method arguments as the constructor arguments for the new ManagedConnection. You can optionally add additional logic to these methods by implementing one or more of them in the level three ManagedConnectionFactory class.
protected ICONConnection instantiateConnection(ICONManagedConnection mc)
When the client application requests a new ConnectionFactory, the resource adapter uses this method to create that new object. The implementation of this method is generated in its super class base.spi.ManagedConnectionFactoryBase. The following is the generated implementation from the COTS sample resource adapter in the base.spi.COTSManagedConnectionFactoryBase.java:
return new COTSConnectionFactory(mcf);
You should override this method and provide your implementation if you need to alter this default logic in any way. In your implementation, be certain that you instantiate the level three ConnectionFactory class.
spi.ManagedConnectionMetaData
public String getEISProductName ()
public String getEISProductVersion()
public int getMaxConnections()
public String getUserName()
You can customize each of these methods to interrogate the EIS at run-time to provide current information about the EIS to which the resource adapter is currently connected. The "Customized ManagedConnectionMetaData.getUserName method from DBMS Sample" code example shows the customized getUserName method in the DBMS sample resource adapter.
Customizing the Resource Adapter's JIOs
Recall that Java Interaction Objects (JIOs) provide a convenient way for an application to invoke an EIS API method using the resource adapter's generated classes. This section describes how to customize the resource adapter JIOs. The following topics are described:
- JIO Class Naming Scheme
- Generated JIO - Code Sample
- JIO Generation Options
- Advanced Customizations (optional)
Note that all JIO customizations are considered advanced because there are no explicit customization points in the generated JIO classes. Instead, you are free to revise the code in the generated methods, taking care to preserve any required logic.
JIO Class Naming Scheme
Sun ONE Connector Builder provides default names for all the generated JIO classes. The names for JIO classes related to the EIS API methods are constructed from several values as listed in "Names for Classes Related to the EIS API Method".
The following is the general pattern for the JIO classes that are generated:
[EIS API class name][EIS API method name]
For the getCustomer method in the COTS example Sun ONE Connector Builder generates JIO class named:
COTSAPIGetCustomer.
The Execute and ExecuteAPI Methods
JIOs provide two sets of methods for client interaction. While the overloaded execute methods operate on the inputRecord, the overloaded executeAPI methods operate on the parameters that the API method itself operates on. This leaves the choice with the clients whether to prepare the inputRecord or simply use the APIs parameters to access the JIO.
Generated JIO - Code Sample
Upon generation you should find the JIOs generated in the resource adapter source directory, in a subdirectory named `jio' in the specified package directory structure.
Each generated JIO extends ICONJavaInteractionObject available as part of Level 1 classes. The ICONJavaInteractionObject provides the base functionality for all the generated JIOs. JIOs belong in Level 3 in the class hierarchy and no Level 2 classes are generated for JIOs. They are customizable as required.
The code example below shows the methods of a generated JIO for the COTSAPIGetCustomerISpec Interaction Spec. It maps to the getCustomer method in the COTSAPI class. For the complete source refer to the JIOs generated for COTS resource adapter under:
<connector_builder_install_root>/samples/cots/adapters/COTS/src/com /sun/appinteg/samples/cots/jio.
JIO Generation Options
Through the resource adapter definition, the adapter developer can specify additional characteristics of the JIOs generated.
Expose Function Name
If the JIO for a given Interaction Spec is customized to expose the function name, Sun ONE Connector Builder generates the JIO execute methods with function name as an additional input parameter. This parameter is used to set the function name on the Interaction Spec being executed. In the generated code the setFunctionName() method is called on the Interaction Spec before execution.
This functionality is useful in the development of resource adapter using a general-purpose EIS API.
Start Local Transaction
If the JIO for a given Interaction Spec is customized to start a local transaction, Sun ONE Connector Builder generates additional code in the JIO execute method that gets the local transaction associated with the connection and performs the start, commit or rollback operations at appropriate times.
This functionality is useful to ensure that the interaction spec execution does happen in a strict transactional context. Note: you do not need to choose this option if the clients to this JIO are J2EE applications where transaction semantics can be controlled via declarative deployment descriptors. Choosing this option for the JIO provides similar functionality as deploying it's client with a "requiredNew" transaction semantic.
Advanced Customizations (optional)
It is usually not required to customize the Sun ONE Connector Builder generated JIOs. They are mostly functional just as generated and perform various runtime checks and validations. They also capture any runtime exceptions and throw them to the client. A few customizations are available at the adapter definition level as discussed above.
The following scenarios give general guidelines on when to customize JIOs.
Provide Connection Spec Properties for getConnection Call
Sun ONE Connector Builder generated JIOs use the getConnection method (with no input parameters) to acquire a connection. This is most suited for managed environments where the security management and caller identity are managed by the container. If specific connection spec properties have to be sent to getConnection method, the JIO execute method needs to be customized to accommodate this change.
Embedding Extra Log Messages in JIO
For debugging the resource adapter, you sometimes may need to put extra log messages in the JIO code. You can use the logMessage and logException methods available in the JIO. These messages are written out to the PrintWriter instance configured through the setLogWriter method of the JIO, by the calling application.
Restricting Usage of the Connector at Runtime
Access to JIO can be restricted by customizing the execute method to verify the caller credential through the J2EE API and prepare a violation exception to throw to the user. This activity can be logged through the JIO logs as specified in Embedding Extra Log Messages in JIO, for future reference and auditing.
Preserving Customizations to the JIOs
If you never change the resource adapter definition, for example, by changing the iSpec name or JIO name, then the generated customizable classes are never overwritten thus preserving the customizations. However, if you change the adapter definition that necessitates a change in the generated code, the affected files are regenerated. The original file which you customized is available to you as a .bak (or .bak, .bak2 etc.) file so that you can copy your customizations to the new file. The regeneration report contains details of what files are re-written and what files are preserved. Refer to "Preserving Customizations" for more details on the regeneration. The JIOs are regenerated if you change the following characteristics of the adapter definition.
- when the iSpec name has changed
- when the JIO name has changed
- when expose function name selection is altered
- when start local transaction selection is altered
- when input/output record names have changed
- when the connection parameter information is changed
- when the input parameter names have changed