Enabling heritage programming models

You can enable your applications that use deprecated application programming models (APIs) in WebSphere® Application Server traditional to run on WebSphere Application Server Liberty with the heritageAPIs-1.1 feature. This feature provides an alternative to migrating your applications so that you can use the same WebSphere Application Server traditional application on Liberty without changing the code.

About this task

The following heritage programming models are available when you enable the heritageAPIs-1.1 feature. Use these APIs only to enable existing applications that run on the traditional server to run on Liberty and not for new development.

CommonJ Timer and Work Manager APIs
WebSphere Application Server traditional provides the now-deprecated CommonJ Timer, and Work Manager features. You can update applications that use these deprecated scheduling facilities to use the standard Concurrency Utilities for Java EE. If that option is not feasible, you can access these facilities in Liberty 22.0.0.1 and later by enabling the heritageAPIs-1.1 feature.
Extensions to Java Database Connectivity (JDBC)
In WebSphere Application Server traditional, applications use the WSCallHelper interface to access nonstandard vendor-specific JDBC APIs. For Liberty, use the JDBC wrapper pattern, which is a more standard JDBC specification-based approach. If the JDBC wrapper pattern is not a feasible option, applications can access the WSCallHelper APIs on Liberty version 22.0.0.1 and later by enabling the heritageAPIs-1.1 feature.

Enabling the CommonJ Timer and Work Manager APIs

  1. Configure your server.xml file to enable the CommonJ Timer and Work Manager APIs.
    To enable these APIs, you must specify both the heritageAPIs-1.1 and concurrent-1.0 features and one or more commonjTimerManager or managedExecutorService configuration elements, as shown in the following server.xml file example. This example also specifies the jndi-1.0 feature to enable JNDI lookups and the servlet-3.0 feature to define resource references in the web.xml file.
    <server>
      <featureManager>
        <feature>concurrent-1.0</feature>
        <feature>heritageAPIs-1.1</feature>
        <feature>jndi-1.0</feature> 
        <feature>servlet-3.0</feature> 
      </featureManager>
    
      <commonjTimerManager id="MyTimerManager" jndiName="timer/myTimerMgr"
        contextServiceRef="DefaultContextService"
        maxConcurrency="5"/>
    
      <managedExecutorService id="MyWorkManager" jndiName="wm/myWorkMgr"
        contextServiceRef="DefaultContextService">
        <concurrencyPolicy max="5" maxQueueSize="20"/>
      </managedExecutorService>
    
      ...
    </server>
  2. Make the TimerManager and WorkManager interfaces available to your application.
    To make these interfaces available to your application, first define resource references to them in a deployment descriptor, such as a web.xml file, as shown in the following example.
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-app_3_0.xsd"
        id="WebApp_ID">
        
      <resource-ref>
        <res-ref-name>java:comp/env/timer/myTimerMgrRef</res-ref-name>
        <res-type>commonj.timers.TimerManager</res-type>
        <res-sharing-scope>Unshareable</res-sharing-scope>
        <lookup-name>timer/myTimerMgr</lookup-name>
      </resource-ref>
    
      <resource-ref>
        <res-ref-name>java:comp/env/wm/myWorkMgrRef</res-ref-name>
        <res-type>commonj.work.WorkManager</res-type>
        <lookup-name>wm/myWorkMgr</lookup-name>
      </resource-ref>
    
    </web-app>
    You can then look up the references from your application code, as shown in the following example.
    TimerManager myTimerMgr = InitialContext.doLookup("java:comp/env/timer/myTimerMgrRef");
    WorkManager myWorkMgr = InitialContext.doLookup("java:comp/env/wm/myWorkMgrRef");
    Instead of a deployment descriptor file, you can use the @Resource annotation in your application code to define resource references and inject TimerManager and WorkManager instances into the corresponding fields of web or EJB components.
    @WebServlet(urlPatterns = "/MyServlet")
    public class MyServlet extends HttpServlet {
        @Resource(name = "java:comp/env/timer/myTimerMgrRef", lookup = "timer/myTimerMgr", shareable = false)
        TimerManager myTimerMgr;
    
        @Resource(name = "java:comp/env/wm/myWorkMgrRef, lookup = "wm/myWorkMgr")
        WorkManager myWorkMgr;

You can now run your WebSphere Application Server traditional applications that use the CommonJ Timer and Work Manager APIs on Liberty.

Enabling heritage extensions to JDBC

Configure your server.xml file to enable the available heritage extension to JDBC.

  1. Specify both the heritageAPIs-1.1 and one of the Liberty JDBC features in your server.xml file.

    Specifying these features enables the heritage API within the com.ibm.websphere.rsadapter and com.ibm.websphere.ce.cm packages and also makes the heritageSettings configuration element available. The following example enables the heritageAPIs-1.1 and jdbc-4.2 features. It also specifies the jndi-1.0 feature to enable JNDI lookups.

  2. Configure heritageSettings and identifyException elements in your server.xml file.
    These elements are subelements of the dataSource element that is used to configure JDBC data sources, as shown in the following server.xml file example.
    <server>
      <featureManager>
        <feature>heritageAPIs-1.1</feature>
        <feature>jdbc-4.2</feature>
        <feature>jndi-1.0</feature> 
        ...
      </featureManager>
    
      <dataSource id="MyDataSource" jndiName="jdbc/myDataSource" type="javax.sql.XADataSource">
        <jdbcDriver libraryRef="MySQL" javax.sql.XADataSource="com.mysql.cj.jdbc.MysqlXADataSource"/>
        <properties databaseName="exampledb" serverName="localhost" portNumber="3306"/>
        <containerAuthData user="dbuser1" password="dbpwd1"/>
        <heritageSettings helperClass="com.ibm.websphere.rsadapter.GenericDataStoreHelper" replaceExceptions="true"/>
        <identifyException sqlState="S1000" as="None"/>
        <identifyException errorCode="1022" as="com.ibm.websphere.ce.cm.DuplicateKeyException"/>
        <identifyException errorCode="1077" as="StaleConnection"/>
        <identifyException errorCode="1079" as="StaleConnection"/>
      </dataSource>
    </server>

    The replaceExceptions attribute of heritageSettings element replaces occurrences of the java.sql.SQLException exceptions with a type that is designated by one or more identifyException elements or by the built-in identification, which can come from a DataStoreHelper implementation.

    The identifyException element in Liberty can be used in place of the WebSphere Application Server traditional userDefinedErrorMap data source custom property. The previous example configuration is equivalent to the following userDefinedErrorMap value.
     "S1000"=;1022=com.ibm.websphere.ce.cm.DuplicateKeyException;1077=com.ibm.websphere.ce.cm.StaleConnectionException;1079=com.ibm.websphere.ce.cm.StaleConnectionException

You can now run your WebSphere Application Server traditional applications that use the following heritage extensions to JDBC on Liberty.

DataStoreHelper
  • Use the DataStoreHelper class from WebSphere Application Server traditional to programmatically adjust differences between JDBC drivers or databases in Liberty.
  • Applications that are migrating from WebSphere Application Server traditional can use DataStoreHelper implementations from Liberty or configure custom DataStoreHelper implementations by enabling the heritiageAPIs-1.1 feature and including the following configuration in the server.xml file:
    <featureManager>
      <feature>jdbc4.2[+]</feature>
      <feature>heritageAPIs-1.1</feature>
    </featureManager>
    
    <dataSource ...>
      ...
      <heritageSettings helperClass="fully.qualified.class.name" />
    </dataSource>
    
WSCallHelper
  • WSCallHelper is a WebSphere Application Server traditional API that helps you safely invoke vendor-specific APIs on JDBC drivers.
  • WSCallHelper includes minor methods for obtaining a DataStoreHelper class, clearing the statement cache, and programmatically marking a connection as stale.
  • Applications that are migrating from WebSphere Application Server traditional can use the WSCallHelper API by enabling the heritiageAPIs-1.1 feature.

The following example shows how to call the createArray method on a connection that is wrapped for the oracle.jdbc.OracleConnection instance by using the WSCallHelper API:

array = (oracle.sql.Array) WSCallHelper.jdbcCall(
  null, 
  con, 
  "createArray",
  new Object[] { typeName, elements },
  new Class[] { String.class, Object.class }
);
For more information, see the Oracle Connection Javadoc.
WSDataSource and JDBCConnectionSpec
  • WSDataSource and JDBCConnectionSpec are interfaces for requesting a connection with attributes beyond user or password.
  • Applications that are migrating from WebSphere Application Server traditional can use the WSDataSource and JDBCConnectionSpec APIs by enabling the heritiageAPIs-1.1 feature.

The following example shows how to cast a generic DataSource instance to the WSDataSource API and use the WebSphere Application Server traditional API to get a connection with the transactionIsolation attribute set to TRANSACTION_READ_COMMITTED:

tx.begin();
JDBCConnectionSpec req = WSRRAFactory.createJDBCConnectionSpec();
req.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
con1 = ((WSDataSource) ds).getConnection(req);
...  con1.close();
con2 = ((WSDataSource) ds).getConnection(req);
...  con2.close();
tx.commit();
Exception Mapping
  • Exception Mapping provides exceptions from WebSphere Application Server traditional that extend the SQLException function but are specific to database error states. For example, when a duplicate key error is detected, the com.ibm.websphere.ce.cm.DuplicateKeyException exception is thrown.
  • Applications that are migrating from WebSphere Application Server traditional can intercept these exceptions to handle them differently than a generic SQLException exception, enable the heritiageAPIs-1.1 feature and specify the heritageSettings replaceExceptions attribute, as shown in the following example:
    <featureManager>
      <feature>jdbc4.2[+]</feature>
      <feature>heritageAPIs-1.1</feature>
    </featureManager>
    
    <dataSource ...>
      ...
      <heritageSettings replaceExceptions="true" />
    </dataSource>
    

The following example shows how to catch the WebSphere Application Server traditional DuplicateKeyException exception and handle it while also still catching a SQLException exception:

try ( Connection con = ds.getConnection(); Statement stmt = con.createStatement(); ) {
  // use connection
} catch (com.ibm.websphere.ce.cm.DuplicateKeyException dup) {
  // handle duplicate key error
} catch (SQLException sqle) {
  // handle all other exceptions
The following DataStoreHelper implementations are available in Liberty when the heritageAPIs-1.1 feature is enabled.
com.ibm.websphere.rsadapter.GenericDataStoreHelper
This implementation is an extensible starting point for all JDBC driver vendors.
com.ibm.websphere.rsadapter.ConnectJDBCDataStoreHelper
This implementation is for DataDirect Connect for JDBC drivers.
com.ibm.websphere.rsadapter.DB2AS400DataStoreHelper
This implementation is for Db2 on IBM i.
com.ibm.websphere.rsadapter.DB2UniversalDataStoreHelper
This implementation is for the IBM Data Server Driver for JDBC and SQLJ for Db2, which is also known as the Db2 JCC driver.
com.ibm.websphere.rsadapter.DerbyDataStoreHelper
This implementation is for Derby Embedded.
com.ibm.websphere.rsadapter.DerbyNetworkServerDataStoreHelper
This implementation is for Derby Network Client.
com.ibm.websphere.rsadapter.InformixDataStoreHelper
This implementation is for the Informix JDBC driver.
com.ibm.websphere.rsadapter.InformixJccDataStoreHelper
This implementation is for the IBM Data Server Driver for JDBC and SQLJ for Informix.
com.ibm.websphere.rsadapter.MicrosoftSQLServerDataStoreHelper
This implementation is for the Microsoft SQL Server JDBC Driver.
com.ibm.websphere.rsadapter.Oracle11gDataStoreHelper
This implementation is for Oracle 11g and later.
com.ibm.websphere.rsadapter.Sybase11DataStoreHelper
This implementation is for Sybase 11.9.2 and later.
The following SQLException extension types are available in Liberty when the heritageAPIs-1.1 feature is enabled.
com.ibm.websphere.ce.cm.DuplicateKeyException
com.ibm.websphere.ce.cm.ObjectClosedException
com.ibm.websphere.ce.cm.StaleConnectionException
com.ibm.websphere.ce.cm.StaleStatementException
com.ibm.websphere.ce.cm.PortableSQLException
This extension type is a superclass of the other extension types.
The following heritage APIs that provide extensions to JDBC are available in Liberty when the heritageAPIs-1.1 feature is enabled.
com.ibm.websphere.rsadapter.JDBCConnectionSpec
com.ibm.websphere.rsadapter.WSCallHelper
com.ibm.websphere.rsadapter.WSConnectionSpec
com.ibm.websphere.rsadapter.WSDataSource
com.ibm.websphere.rsadapter.WSRRAFactory
An application can create a ConnectionSpec object with specific connection attributes set on it and use it to request a connection, as shown in the following example:
import com.ibm.websphere.rsadapter.WSRRAFactory; 
import com.ibm.websphere.rsadapter.JDBCConnectionSpec; 
import com.ibm.websphere.rsadapter.WSDataSource; 
JDBCConnectionSpec spec = WSRRAFactory.createJDBConnectionSpec(); spec.setReadOnly(true); 
WSDataSource wsDs = InitialContext.doLookup(“jdbc/myDB”); 
Connection con = wsDs.getConnection(spec);

These JDBC heritage API classes are bundled in the com.ibm.ws.jdbc.heritage.api_.jar that is located in the wlp/lib/ directory.