back to all blogsSee all blog posts

Support for sharding keys with JDBC 4.3 in 19.0.0.2

image of author
Laura Cowen on Mar 1, 2019
Post available in languages:

In the second of our new 4-weekly Open Liberty releases, we have:

View the list of fixed bugs from 19.0.0.2

If you’re using Maven, here are the coordinates:

<dependency>
    <groupId>io.openliberty</groupId>
    <artifactId>openliberty-runtime</artifactId>
    <version>19.0.0.2</version>
    <type>zip</type>
</dependency>

Or for Gradle:

dependencies {
    libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '[19.0.0.2,)'
}

Or if you’re using Docker:

docker pull open-liberty

Or take a look at our Downloads page.

Ask a question on Stack Overflow

New or updated in Open Liberty 19.0.0.2

Support for sharding keys (JDBC 4.3)

The jdbc-4.3 feature updates Liberty to fully integrate with JDBC 4.3 compliant JDBC drivers. It also permits the use of JDBC drivers at older specification levels. The main update in JDBC 4.3 is support for sharding keys. JDBC 4.3 also includes a fluent connection builder API.

To enable the JDBC 4.3 feature in your server.xml:

<featureManager>
  <feature>jdbc-4.3</feature>
  <feature>jndi-1.0</feature> <!-- if JNDI lookup is desired -->
  ... other features used by your application
</featureManager>

<dataSource jndiName="jdbc/oracle">
  <jdbcDriver libraryRef="oracleLib"/>
  <properties.oracle URL="jdbc:oracle:thin:@//localhost:1521/SAMPLEDB"/>
  <containerAuthData user="user1" password="pwd1"/>
</dataSource>

<library id="oracleLib">
    <file name="C:/Oracle/lib/ojdbcX.jar"/>
</library>

Then, initialize within the application:

@Resource(lookup = "jdbc/oracle")
DataSource ds;
...
// Sharding key instances should always be cached and reused, because the JDBC 4.3 API
// provides no guarantee that the JDBC driver will provide any means for equality comparisons.
ShardingKeyBuilder keybuilder = ds.createShardingKeyBuilder();
ShardingKey shardkey1 = keybuilder.subkey("MyShardingKey", JDBCType.VARCHAR).build();

Other application code:

ConnectionBuilder conbuilder = ds.createConnectionBuilder().shardingKey(shardkey1);
try (Connection con = conbuilder.build()) {
    ... use connection to access database
}

Read more about the JDBC 4.3 API.

Support for hashed passwords in quickStartSecurity configuration (Application Security 2.0, 3.0)

User passwords in the quickStartSecurity user registry can now be hashed. Security best practices suggest using one-way hashing when storing passwords. The quickStartSecurity user registry now supports using one-way hashing for passwords.

To enable hashing in quickStartSecurity:

Start by generating a hashed password using the securityUtility script, which you can find in the $INSTALL_ROOT/bin directory:

    bash$ securityUtility encode --encoding=hash password
    {hash}ATAAAAAIzT2+hBgu8khAAAAAIOkF38PjTrrhOFcytyV08lg3dQR0D52oOz+lcoJ1Kpn9

Copy the hashed password and paste it into the value for the userPassword attribute in the quickStartSecurity element of your server.xml:

<quickStartSecurity userName="admin" userPassword="{hash}ATAAAAAIzT2+hBgu8khAAAAAIOkF38PjTrrhOFcytyV08lg3dQR0D52oOz+lcoJ1Kpn9" />

Ready to give it a try?

Get the Maven or Gradle coordinates (and other download options) from the top of this post.

Ask a question on Stack Overflow

Previews of early implementations available in the latest development builds

You can now also try out early implementations of some new capabilities in the latest Open Liberty development builds:

These early implementations are not available in 19.0.0.2 but you can try them out by downloading the latest Open Liberty development build. Let us know what you think!

MicroProfile Concurrency 1.0

MicroProfile Concurrency allows you to create completion stages that run with predictable thread context regardless of which thread the completion stage action ends up running on.

MicroProfile Concurrency provides completion stages that run with predictable thread context that also benefit from being backed by the automatically-tuned Liberty global thread pool. Configuration of concurrency constraints and context propagation is possible programmatically with builders as well as by CDI annotations which can be overriden via MicroProfile Config.

It should be noted that this implementation does not yet include thread context capture & propagation for CDI context, but other context types should be working.

To enable the MicroProfile Concurrency 1.0 feature in your server.xml:

<featureManager>
    <feature>mpConcurrency-1.0</feature>
    <feature>cdi-2.0</feature> <!-- If CDI injection is desired -->
    <feature>jndi-1.0</feature> <!-- used in example -->
    ... other features
  </featureManager>

Example usage in a CDI bean:

@Inject @ManagedExecutorConfig(maxAsync=5, propagated=ThreadContext.APPLICATION)
ManagedExecutor executor;
...
CompletableFuture<Integer> stage = executor
    .supplyAsync(supplier1)
    .thenApply(function1)
    .thenApplyAsync(value -> {
        try {
            // access resource reference in application's java:comp namespace,
            DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/ds1");
            ...
            return result;
        } catch (Exception x) {
            throw new CompletionException(x);
        }
    });

Example usage of programmatic builders:

ManagedExecutor executor = ManagedExecutor.builder()
    .maxAsync(5)
    .propagated(ThreadContext.APPLICATION, ThreadContext.SECURITY)
    .build();

CompletableFuture<Integer> stage1 = executor.newIncompleteFuture();
stage1.thenApply(function1).thenAccept(value -> {
    try {
        // access resource reference in application's java:comp namespace,
        DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/ds1");
        ...
    } catch (Exception x) {
        throw new CompletionException(x);
    }
};
...
stage1.complete(result);

For more information:

Support for Oracle Universal Connection Pool (UCP) (JDBC 4.x)

Support for Oracle Universal Connection Pool (UCP) has been implemented in latest Open Liberty development build. Oracle UCP is a connection pool which can be used in place of Open Liberty’s connection pool to take advantage of Oracle’s high availability functionality.

Using Oracle UCP is now supported with Liberty in the 19.0.0.2 beta. This will allow users of Oracle Real Application Clusters (RAC) to take advantage of Oracle’s high availability and performance functionality such as Fast Connection Failover (FCF), Fast Application Notification (FAN) and Oracle Notification Services (ONS).

To use Oracle UCP with Liberty add one of the JDBC features to server.xml:

<featureManager>
  <feature>jdbc-4.2</feature> <!-- Any of the other JDBC features could also be used -->
  <feature>jndi-1.0</feature> <!-- if JNDI lookup is desired -->
  <!-- Include any other features needed by your application -->
</featureManager>

Also add to the server.xml a library referencing the UCP jar and Oracle JDBC driver (both of which can be obtained from Oracle):

<library id="OracleUCPLib">
    <fileset dir="C:/Oracle/Drivers" includes="ojdbc8.jar ucp.jar"/>
</library>

And add a datasource using the new properties.oracle.ucp element:

<dataSource id="DefaultDataSource" jndiName="jdbc/oracleUCP" type="javax.sql.XADataSource">
    <jdbcDriver libraryRef="OracleUCPLib" />
    <containerAuthData user="user" password="pwd"/>
    <properties.oracle.ucp URL="jdbc:oracle:thin:@//localhost:1521/SAMPLEDB" connectionFactoryClassName="oracle.jdbc.xa.client.OracleXADataSource"/>
</dataSource>

Add any desired config (such as maxPoolSize or fastConnectionFailoverEnabled) to the properties.oracle.ucp element. It is important to note that when using Oracle UCP, Open Liberty’s connection pooling is disabled. As a result, the following data source properties are ignored: statementCacheSize and validationTimeout. The following connection manager properties are also ignored: agedTimeout, connectionTimeout, maxIdleTime, maxPoolSize, minPoolSize, purgePolicy, reapTime, maxConnectionsPerThread, maxConnectionsPerThreadLocal. Use the equivalent Oracle UCP functionality.

The standard JDBC APIs can be used to access the datasource.