5 Using WebLogic Wrapper Drivers

This chapter describes how to use deprecated WebLogic wrapper drivers with WebLogic Server 10.3.6.

Note:

Oracle recommends that you use DataSource objects to get database connections in new applications. DataSource objects (WebLogic data sources and multi data sources), along with the JNDI tree, provide access to pooled connections in a data source for database connectivity. The WebLogic wrapper drivers are deprecated. For existing or legacy applications that use the JDBC 1.x API, you can use the WebLogic wrapper drivers to get database connectivity.

This chapter includes the following sections:

Using the WebLogic RMI Driver (Deprecated)

Note:

RMI driver client functionality is deprecated and will be removed in future release. None of the features introduced in WLConnection and WLDataSource for this release are supported by RMI driver clients, see "New and Changed JDBC Data Source Features in This Release" in Programming JDBC for Oracle WebLogic Server.

A RMI driver client makes connections to the DBMS by looking up the DataSource object. This lookup is accomplished by using a Java Naming and Directory Service (JNDI) lookup, or by directly calling WebLogic Server which performs the JNDI lookup on behalf of the client.

The RMI driver replaces the functionality of both the WebLogic t3 driver (deprecated) and the Pool driver (deprecated), and uses the Java standard Remote Method Invocation (RMI) to connect to WebLogic Server rather than the proprietary t3 protocol.

Because the details of the RMI implementation are taken care of automatically by the driver, a knowledge of RMI is not required to use the WebLogic JDBC/RMI driver.

RMI Driver Client Interoperability

Interoperability with earlier WebLogic Server releases is limited. Participants (client/server or servers-to-server) must be from the same major release. Early 10.x clients can be updated to interoperate with later point and patch set releases by adding the ucp.jar to the CLASSPATH.

Security Considerations for WebLogic RMI Drivers

Prior to WebLogic Server 10.3.2.0, RMI driver clients allowed unauthorized RMI access to a DataSource object which is a potential security vulnerability as it may provide a client uncontrolled access to a database. Oracle recommends replacing RMI driver clients with WebLogic data sources and multi data sources in these environments or implementing strong network security measures when RMI driver clients are used.

For servers in WebLogic Server 10.3.2.0 and later domains, RMI access to DataSource objects is controlled at the server level by the weblogic.jdbc.remoteEnabled system property and is disabled by default. To enable RMI driver clients to access DataSource objects, set the value of the weblogic.jdbc.remoteEnabled property to true. Oracle recommends replacing RMI driver clients with WebLogic data sources and multi data sources or implementing strong network security measures when RMI driver clients are used.

Note:

The weblogic.jdbc.remoteEnabled system property is deprecated in WebLogic Server 10.3.6.0.

For servers in WebLogic Server 10.3.6.0 and higher domains, you can secure RMI driver client communication with DataSource objects at the server level by setting the RMI JDBC Security parameter to Secure.

Valid values are:

  • Secure—All incoming JDBC calls made over RMI by remote clients and servers are disabled. All incoming JDBC calls use JTS and have administrator authentication. All other subjects, including anonymous, are rejected. This option requires one of the following:

    If security is not configured, all operations fail with an exception.

  • Compatibility—Use an unsecure channel with the application's subject and no administrator authentication when using RMI to access a data source. This setting reflects the legacy implementation behavior for RMI access to a data source and is a potential security vulnerability as it provides a client uncontrolled access to a database. This setting should only be used when strong network security is in place. Compatibility is the default value.

See "Enable RMI JDBC security" in the Oracle WebLogic Server Administration Console Help.

Note:

If the weblogic.jdbc.remoteEnabled system property is set to true, it overrides the RMI JDBC Security and provides backward compatibility with existing applications.

Setting Up WebLogic Server to Use the WebLogic RMI Driver

The RMI driver is accessible through DataSource objects, which are created in the Administration Console. You should create DataSource objects in your WebLogic Server configuration before you use the RMI driver in your applications.

Sample Client Code for Using the RMI Driver

The following code samples show how to use the RMI driver to get and use a database connection from a WebLogic Server data source.

Import the Required Packages

Before you can use the RMI driver to get and use a database connection, you must import the following packages:

javax.sql.DataSource 
java.sql.*
java.util.*
javax.naming.*

Get the Database Connection

The WebLogic JDBC/RMI client obtains its connection to a DBMS from the DataSource object that you defined in the Administration Console. There are two ways the client can obtain a DataSource object:

  • Using a JNDI lookup. This is the preferred and most direct procedure.

  • Passing the DataSource name to the RMI driver with the Driver.connect()method. In this case, WebLogic Server performs the JNDI look up on behalf of the client.

Using a JNDI Lookup to Obtain the Connection

To access the WebLogic RMI driver using JNDI, obtain a context from the JNDI tree by looking up the name of your DataSource object. For example, to access a DataSource called "myDataSource" that is defined in Administration Console:

Context ctx = null;
  Hashtable ht = new Hashtable();
  ht.put(Context.INITIAL_CONTEXT_FACTORY,
         "weblogic.jndi.WLInitialContextFactory");
  ht.put(Context.PROVIDER_URL,
         "t3://hostname:port");
  try {
    ctx = new InitialContext(ht);
    javax.sql.DataSource ds 
      = (javax.sql.DataSource) ctx.lookup ("myDataSource");
   java.sql.Connection conn = ds.getConnection();
   // You can now use the conn object to create 
   //  a Statement object to execute
   //  SQL statements and process result sets:
   Statement stmt = conn.createStatement();
   stmt.execute("select * from someTable");
   ResultSet rs = stmt.getResultSet(); 
   // Do not forget to close the statement and connection objects
   //  when you are finished:
 }
  catch (Exception e) {
    // a failure occurred
    log message;
  }
} finally {    
  try { 
    ctx.close(); 
  } catch (Exception e) {
     log message; }
  try { 
    if (rs != null) rs.close(); 
  } catch (Exception e) {  
     log message; }
  try { 
    if (stmt != null) stmt.close(); 
  } catch (Exception e) {  
     log message; }
  try { 
    if (conn != null) conn.close(); 
  } catch (Exception e) {  
     log message; }
}

(Where hostname is the name of the machine running your WebLogic Server and port is the port number where that machine is listening for connection requests.)

In this example a Hashtable object is used to pass the parameters required for the JNDI lookup. There are other ways to perform a JNDI lookup. For more information, see Programming JNDI for Oracle WebLogic Server.

Notice that the JNDI lookup is wrapped in a try/catch block in order to catch a failed look up and also that the context is closed in a finally block.

Using Only the WebLogic RMI Driver to Obtain a Database Connection

Instead of looking up a DataSource object to get a database connection, you can access WebLogic Server using the Driver.connect() method, in which case the JDBC/RMI driver performs the JNDI lookup. To access the WebLogic Server, pass the parameters defining the URL of your WebLogic Server and the name of the DataSource object to the Driver.connect() method. For example, to access a DataSource called "myDataSource" as defined in the Administration Console:

java.sql.Driver myDriver = (java.sql.Driver)
  Class.forName("weblogic.jdbc.rmi.Driver").newInstance();
String url = "jdbc:weblogic:rmi";
java.util.Properties props = new java.util.Properties();
props.put("weblogic.server.url", "t3://hostname:port");
props.put("weblogic.jdbc.datasource", "myDataSource");
java.sql.Connection conn = myDriver.connect(url, props);

(Where hostname is the name of the machine running your WebLogic Server and port is the port number where that machine is listening for connection requests.)

You can also define the following properties which will be used to set the JNDI user information:

  • weblogic.user—specifies a username

  • weblogic.credential—specifies the password for the weblogic.user.

Row Caching with the WebLogic RMI Driver

Row caching is a WebLogic Server JDBC feature that improves the performance of your application. Normally, when a client calls ResultSet.next(), WebLogic Server fetches a single row from the DBMS and transmits it to the client JVM. With row caching enabled, a single call to ResultSet.next() retrieves multiple DBMS rows, and caches them in client memory. By reducing the number of trips across the wire to retrieve data, row caching improves performance.

Note:

WebLogic Server will not perform row caching when the client and WebLogic Server are in the same JVM.

You can enable and disable row caching and set the number of rows fetched per ResultSet.next() call with the data source attributes Row Prefetch Enabled and Row Prefetch Size, respectively. You set data source attributes via the Administration Console. To enable row caching and to set the row prefetch size attribute for a data source, follow these steps:

  1. If you have not already done so, in the Change Center of the Administration Console, click Lock & Edit.

  2. In the Domain Structure tree, expand Services > JDBC, then select Data Sources.

  3. On the Summary of Data Sources page, click the data source name.

  4. Select the Configuration: General tab and then do the following:.

    1. Select the Row Prefetch Enabled check box.

    2. In Row Prefetch Size, type the number of rows you want to cache for each ResultSet.next() call.

  5. Click Save.

  6. To activate these changes, in the Change Center of the Administration Console, click Activate Changes.

See the JDBC Data Source: Configuration: General page in the Oracle WebLogic Server Administration Console Help.

Important Limitations for Row Caching with the WebLogic RMI Driver

Keep the following limitations in mind if you intend to implement row caching with the RMI driver:

  • WebLogic Server only performs row caching if the result set type is both TYPE_FORWARD_ONLY and CONCUR_READ_ONLY.

  • Certain data types in a result set may disable caching for that result set. These include the following:

    • LONGVARCHAR/LONGVARBINARY

    • NULL

    • BLOB/CLOB

    • ARRAY

    • REF

    • STRUCT

    • JAVA_OBJECT

  • Certain ResultSet methods are not supported if row caching is enabled and active for that result set. Most pertain to streaming data, scrollable result sets or data types not supported for row caching. These include the following:

    • getAsciiStream()

    • getUnicodeStream()

    • getBinaryStream()

    • getCharacterStream()

    • isBeforeLast()

    • isAfterLast()

    • isFirst()

    • isLast()

    • getRow()

    • getObject (Map)

    • getRef()

    • getBlob()/getClob()

    • getArray()

    • getDate()

    • getTime()

    • getTimestamp()

Limitations When Using Global Transactions

Populating a RowSet in a global transaction may fail with "Fetch Out Of Sequency" exception. For example:

  1. When the RMI call returns, the global transaction is suspended automatically by the server instance.

  2. The JDBC driver invalidates the pending ResultSet object to release the system resources.

  3. The client tries to read data from the invalidated ResultSet.

  4. A "Fetch Out Of Sequency" exception is thrown if that data has not been prefetched. Since the number of rows prefetched is vendor specific, you may or may not encounter this issue, especially when working with one or two rows.

If you encounter this exception, make sure to populate the RowSet on the server side and then serialize it back to the client.

Using the WebLogic JTS Driver (Deprecated)

The Java Transaction Services or JTS driver is a server-side Java Database Connectivity (JDBC) driver that provides access to both data sources and global transactions from applications running in WebLogic Server. Connections to a database are made from a data source and use a JDBC driver in WebLogic Server to connect to the Database Management System (DBMS) on behalf of your application. Your application uses the JTS driver to access a connection from the data source.

WebLogic Server also uses the JTS driver internally when a connection from a data source that uses a non-XA JDBC driver participates in a global transaction (Logging Last Resource and Emulate Two-Phase Commit). This behavior enables a non-XA resource to emulate XA and participate in a two-phase commit transaction. See "JDBC Data Source Transaction Options" in Configuring and Managing JDBC Data Sources for Oracle WebLogic Server.

Note:

The WebLogic Server JTS driver only supports T3 protocol when participating connections that use Logging Last Resource (LLR), One-Phase Commit, or Emulate Two-Phase Commit.

Once a transaction begins, all database operations in an execute thread that get their connection from the same data source share the same connection from that data source. These operations can be made through services such as Enterprise JavaBeans (EJB) or Java Messaging Service (JMS), or by directly sending SQL statements using standard JDBC calls. All of these operations will, by default, share the same connection and participate in the same transaction. When the transaction is committed or rolled back, the connection is returned to the pool.

Although Java clients may not register the JTS driver themselves, they may participate in transactions via Remote Method Invocation (RMI). You can begin a transaction in a thread on a client and then have the client call a remote RMI object. The database operations executed by the remote object become part of the transaction that was begun on the client. When the remote object is returned back to the calling client, you can then commit or roll back the transaction. The database operations executed by the remote objects must all use the same data source to be part of the same transaction.

For the JTS driver and your application to participate in a global transaction, the application must call conn = myDriver.connect("jdbc:weblogic:jts", props); within a global transaction. After the transaction completes (gets committed or rolled back), WebLogic Server puts the connection back in the data source. If you want to use a connection for another global transaction, the application must call conn = myDriver.connect("jdbc:weblogic:jts", props); again within a new global transaction.

Sample Client Code for Using the JTS Driver

To use the JTS driver, you must first use the Administration Console to create a data source in WebLogic Server.

This explanation demonstrates creating and using a JTS transaction from a server-side application and uses a data source named "myDataSource."

  1. Import the following classes:

    import javax.transaction.UserTransaction;
    import java.sql.*;
    import javax.naming.*;
    import java.util.*;
    import weblogic.jndi.*;
    
  2. Establish the transaction by using the UserTransaction class. You can look up this class on the JNDI tree. The UserTransaction class controls the transaction on the current execute thread. Note that this class does not represent the transaction itself. The actual context for the transaction is associated with the current execute thread.

    Context ctx = null;
    Hashtable env = new Hashtable();
     
    env.put(Context.INITIAL_CONTEXT_FACTORY,
             "weblogic.jndi.WLInitialContextFactory");
     
    // Parameters for the WebLogic Server. 
    // Substitute the correct hostname, port number 
    // user name, and password for your environment:
    env.put(Context.PROVIDER_URL, "t3://localhost:7001"); 
    env.put(Context.SECURITY_PRINCIPAL, "Fred");
    env.put(Context.SECURITY_CREDENTIALS, "secret");
     
    ctx = new InitialContext(env);
     
    UserTransaction tx = (UserTransaction)
      ctx.lookup("javax.transaction.UserTransaction");
    
  3. Start a transaction on the current thread:

    // Start the global transaction before getting a connection
    tx.begin();
    
  4. Load the JTS driver:

    Driver myDriver = (Driver)
     Class.forName("weblogic.jdbc.jts.Driver").newInstance();
    
  5. Get a connection from the data source:

    Properties props = new Properties();
    props.put("connectionPoolID", "myDataSource");
    
    conn = myDriver.connect("jdbc:weblogic:jts", props); 
    
  6. Execute your database operations. These operations may be made by any service that uses a database connection, including EJB, JMS, and standard JDBC statements. These operations must use the JTS driver to access the same data source as the transaction begun in step 3 in order to participate in that transaction.

    If the additional database operations using the JTS driver use a different data source than the one specified in step 5, an exception will be thrown when you try to commit or roll back the transaction.

  7. Close your connection objects. Note that closing the connections does not commit the transaction nor return the connection to the pool:

    conn.close();
    
  8. Complete the transaction by either committing the transaction or rolling it back. In the case of a commit, the JTS driver commits all the transactions on all connection objects in the current thread and returns the connection to the pool.

    tx.commit();
     
    // or:
     
    tx.rollback();
    

Using the WebLogic Pool Driver (Deprecated)

The WebLogic Pool driver enables utilization of data sources from server-side applications such as HTTP servlets or EJBs. For information about using the Pool driver, see in "Accessing Databases" in Developing Web Applications, Servlets, and JSPs for Oracle WebLogic Server.