back to all blogsSee all blog posts

Testing database connections and Jakarta Data preview in Open Liberty 23.0.0.2-beta

image of author
Michal Broz on Feb 21, 2023
Post available in languages:

Open Liberty 23.0.0.2-beta includes several new enhancements for Liberty InstantOn that simplify the process for creating and restoring checkpoints. Admin Center’s Server Config tool receives new capability to test database connections, and a very early preview of Jakarta Data also makes its beta debut in this release. Also included in this beta is all of Jakarta EE Platform 10 and MicroProfile 6.

The Open Liberty 23.0.0.2-beta includes the following beta features (along with all GA features):

New enhancements for Liberty InstantOn

The Open Liberty 22.0.0.11-beta introduced InstantOn, an exciting new feature that provides incredibly fast startup times for MicroProfile and Jakarta EE applications. Since the initial beta release, we’ve made the following changes and enhancements to make it easier to create and deploy applications with Liberty InstantOn:

  • Removal of the features checkpoint phase

  • Reduced set of required Linux capabilities to checkpoint and restore

  • Simplified container image builds with InstantOn

To learn more about these changes and InstantOn, refer to the New enhancements for Liberty InstantOn in 23.0.0.2-beta blog post.

Testing database connections using Admin Center

Looking for a simple way to test your database connections? With this beta release, you can now validate your connections using the Liberty Admin Center feature. The connection test exercises the same code paths as your applications, giving you confidence in your server configuration. The Admin Center connection validation feature is enabled by REST APIs featured in the Testing database connections in Open Liberty apps with REST APIs blog post.

To enable database connection testing, the following minimum set of features must be present in your server configuration:

    <feature>adminCenter-1.0</feature>
    <feature>restConnector-2.0</feature>
    <feature>mpOpenApi-3.0</feature>

Although this example uses the mpOpenApi-3.0 feature, you can use any MicroProfile OpenAPI version that is compatible with your other features.

To provide an example, we’ll start by testing the server resource DefaultDataSource, which is configured to connect to a Derby database using container authentication with an authentication alias.

The following sample server.xml file enables the features to configure the Admin Center test connection function and configures the connection to the Derby database:

<server description="new server">

    <!-- Enable features -->
    <featureManager>
        <feature>adminCenter-1.0</feature>
        <feature>restConnector-2.0</feature>
        <feature>jdbc-4.3</feature>
        <feature>mpOpenApi-3.0</feature>
    </featureManager>

    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443"/>

    <library id="derby">
      <file name="${server.config.dir}/derby/derby.jar"/>
    </library>

    <dataSource id="DefaultDataSource">
      <jdbcDriver libraryRef="derby"/>
      <!-- Example properties referencing an in-memory Derby Embedded database -->
      <properties.derby.embedded databaseName="memory:defaultdb" createDatabase="create"/>
    </dataSource>

    <authData id="myAuth" user="dbuser" password="dbpass"/>

    <!-- Default SSL configuration enables trust for default certificates from the Java runtime -->
    <ssl id="defaultSSLConfig" trustDefaultCerts="true"/>

    <remoteFileAccess>
       <writeDir>${server.config.dir}</writeDir>
    </remoteFileAccess>

    <basicRegistry id="basic">
       <user name="admin" password="adminpwd"/>
    </basicRegistry>

    <!-- Assign 'admin' to Administrator -->
    <administrator-role>
        <user>admin</user>
    </administrator-role>

</server>

For this server.xml example, you will need to add the Derby jar to the server configuration or use your own database configuration.

  1. Configure a Liberty server using the example server.xml file for guidance and then start the server. After the server is started, you can check the logs to find the URL to navigate to the Admin Center. In the previous example, you can navigate to the Admin Center using the https://localhost:9443/adminCenter/ URL.

  2. Select the Server Config tool.

    Server Config Tool
  3. Select server.xml to edit.

    server.xml
  4. In the Design > Server menu, navigate to the resource you want to test and click the Test button.

    Select resource
  5. Choose the type of authentication your application uses:

    • For applications that use container authentication, choose the Application authentication tab and select whether to use default authentication, specify an authentication alias, or choose a login module configuration.

      For this example, the configuration doesn’t specify default authentication on the dataSource element or configure any login modules. Therefore, you must specify an authentication alias by using the dropdown field.

      Container authentication
    • For applications that use application authentication, choose the Application authentication tab and fill in a valid user name and password for the database resource.

      Application authentication
    • If your application does not use a resource reference and the server.xml doesn’t include enableContainerAuthForDirectLookups="true" in the config element, then choose No resource reference tab and fill in a valid user name and password for the database resource.

    No Resource Reference
  6. Click the Connection Test button to run the test and display the results. The following example shows a successful connection test:

Successful connection test example

In addition to Java Database Connectivity you can also test connections to Jakarta Connectors, Jakarta Messaging and Cloudant Integration resources.

For more information about administering Liberty using a GUI, refer to the Manage Open Liberty with Admin Center documentation.

A very early preview of Jakarta Data

Jakarta Data is a new Jakarta EE specification that aims to standardize the popular Data Repository pattern across relational and NoSQL databases. As the specification is further developed and Jakarta Data providers become available, the Jakarta Data specification is expected to standardize a way to plug in your favorite providers that are currently dominant in the industry, including JNoSQL, to be used in Open Liberty.

For now, Open Liberty is using a test implementation of Jakarta Data to experiment with proposed specification features. This implementation is now available in our beta release so that developers can try out these features and provide feedback to influence the specification as it is being developed. The test implementation currently works with relational databases and operates by redirecting repository operations to the built-in Jakarta Persistence provider. It simulates the entirety of the Jakarta Data beta release, plus some additional proposed features that are being considered.

To use Jakarta Data, start by defining an entity class that corresponds to your data. With relational databases, the entity class corresponds to a database table and the entity properties (public methods and fields of the entity class) generally correspond to the columns of the table.

An entity class can use either of the following annotation schemes:

  • The class can be annotated with jakarta.persistence.Entity and related annotations from Jakarta Persistence.

  • The class can be a Java class without entity annotations, in which case the primary key is inferred from an entity property named id or ending with Id.

Next, define one or more repository interfaces for an entity, annotate those interfaces as @Repository, and inject them into components with CDI. The Jakarta Data provider supplies the implementation of the repository interface for you.

The following example shows a simple entity, a repository, and and a servlet that injects them by CDI:

public class Product { // entity
    public long id;
    public String name;
    public float price;
}

@Repository
public interface Products {
    Product findById(long productId);

    @OrderBy("price")
    List<Product> findByNameContains(String searchFor);

    @Query("UPDATE Product o SET o.price = o.price - (?2 * o.price) WHERE o.id = ?1")
    boolean discount(long productId, float discountRate);

    void save(Product p);
}

public class MyServlet extends HttpServlet {
    @Inject
    Products products;

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        List<Product> found = products.findByNameContains(searchFor);
        ...
    }
}

Refer to a draft of the Jakarta Data specification and the jakarta.data.repository.Repository JavaDoc for instructions on how to properly form repository methods so that the Jakarta Data provider understands them.

Optionally, a repository interface can inherit from built-in interfaces such as jakarta.data.repository.CrudRepository that define commonly used methods like findById and save for you:

@Repository
public interface Products extends CrudRepository<Product, Long> {
    @OrderBy("price")
    List<Product> findByNameContains(String searchFor);

    @Query("UPDATE Product o SET o.price = o.price - (?2 * o.price) WHERE o.id = ?1")
    boolean discount(long productId, float discountRate);
}

Jakarta Data has not yet defined a standard configuration model. For now, the Open Liberty beta reuses the existing defaultDatabaseStore configuration (which defaults to the DefaultDataSource data source) for Jakarta Data. This means the beta of Jakarta Data is currently limited to a single data source. This of course will change as the specification defines more of a configuration model. The data-1.0 Liberty beta feature makes the Jakarta Data API available, and you also need a feature for Jakarta Persistence or JDBC (or at some point in the future, Jakarta NoSQL).

Example server.xml configuration:

<server>
  <featureManager>
    <feature>data-1.0</feature>
    <feature>persistence-3.1</feature> <!-- could use jdbc-4.3 instead -->
    <feature>servlet-6.0</feature> <!-- the example includes a servlet -->
  </featureManager>

  <dataSource id="DefaultDataSource">
    <jdbcDriver libraryRef="PostgreSQL"/>
    <properties.postgresql databaseName="testdb" serverName="localhost" portNumber="5432"/>
    <containerAuthData user="dbuser1" password="dbpwd1"/>
  </dataSource>

  <library id="PostgreSQL">
    <file name="${shared.resource.dir}/jdbc/postgresql.jar"/>
  </library>

  <!-- optional because the following are all defaulted: -->
  <databaseStore id="defaultDatabaseStore" createTables="true" dropTables="false"
          tablePrefix="WLP" dataSourceRef="DefaultDataSource"/>
</server>

You can find the initial 1.0.0-b1 beta release of Jakarta Data on Maven, which corresponds to the Open Liberty 23.0.0.2-beta.

<dependency>
  <groupId>jakarta.data</groupId>
  <artifactId>jakarta-data-api</artifactId>
  <version>1.0.0-b1</version>
</dependency>

Experimental function in the beta of Jakarta Data

This beta provides some additional function that is under consideration for Jakarta Data, but not in the Jakarta Data 1.0.0-b1 beta.

When a global transaction is active on the thread on which a repository operation executes, the repository operation enlists as part of the transaction, if the data source that backs the repository is capable of enlistment. Transaction enlistment is default for relational databases, but you can switch it off by setting the transactional data source configuration attribute to false in your server configuration.

When the the concurrent-3.0 feature is enabled, you can use the @Asynchronous annotation from Jakarta Concurrency on repository methods to enable them to run asynchronously.

@Repository
public interface Products extends CrudRepository<Product, Long> {
    @Asynchronous
    @OrderBy("price")
    CompletableFuture<List<Product>> findByNameContains(String searchFor);

    @Asynchronous
    @Query("UPDATE Product o SET o.price = o.price - (?2 * o.price) WHERE o.id = ?1")
    CompletionStage<Boolean> discount(long productId, float discountRate);
}

You can also try out the ability to define queries annotatively:

@Repository
public interface Products extends CrudRepository<Product, Long> {
    @Filter(by = "name", op = Compare.Contains)
    @Filter(by = "price", op = Compare.LessThanEqual)
    @OrderBy("price")
    List<Product> searchFor(String nameMatch, float maxPrice);

    @Filter(by = "id")
    @Update(attr = "price", op = Operation.Multiply)
    boolean adjustPrice(long productId, float ratio);

    @Delete
    @Filter(by = "name", ignoreCase = true)
    void discontinue(String productName);
}

Your feedback is welcome on all of the Jakarta Data features and will be helpful as the specification develops further. Let us know what you think and/or be involved directly in the specification on github.

Jakarta EE 10 and MicroProfile 6

This beta release also includes Jakarta EE Platform 10 and MicroProfile 6, which were first made available in the 22.0.0.13-beta. To find out more, reference the 22.0.0.13-beta blog post.

Try it now

To try out these features, update your build tools to pull the Open Liberty All Beta Features package instead of the main release. The beta works with Java SE 19, Java SE 17, Java SE 11, and Java SE 8.

If you’re using Maven, you can install the All Beta Features package using the following pom.xml configuration:

<plugin>
    <groupId>io.openliberty.tools</groupId>
    <artifactId>liberty-maven-plugin</artifactId>
    <version>RELEASE</version>
    <configuration>
        <runtimeArtifact>
          <groupId>io.openliberty.beta</groupId>
          <artifactId>openliberty-runtime</artifactId>
          <version>23.0.0.2-beta</version>
          <type>zip</type>
        </runtimeArtifact>
    </configuration>
</plugin>

You must also add dependencies to your pom.xml file for the beta version of the APIs that are associated with the beta features that you want to try. For example, for Jakarta EE 10 and MicroProfile 6, include the following dependencies:

<dependency>
    <groupId>org.eclipse.microprofile</groupId>
    <artifactId>microprofile</artifactId>
    <version>6.0-RC3</version>
    <type>pom</type>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-api</artifactId>
    <version>10.0.0</version>
    <scope>provided</scope>
</dependency>

Or for Gradle:

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

Or take a look at our Downloads page.

For more information on using a beta release, refer to the Installing Open Liberty beta releases documentation.

We welcome your feedback

Let us know what you think on our mailing list. If you hit a problem, post a question on StackOverflow. If you hit a bug, please raise an issue.