A Java Microservice with GraalVM, Micronaut Data, JDK 17-22, and the Oracle Autonomous Database

Juarez Junior
10 min readNov 10, 2023

--

by Juarez Junior

Micronaut.io

Introduction to Micronaut

With the latest release of Micronaut 4, beyond the usual set of killer features like Ahead-of-Time (AOT) compilation and Micronaut’s expression language, there are many interesting additions Java developers should be aware of.

So, I decided to create a blog post about a solution that combines Java with GraalVM, Micronaut Data, and the Oracle Autonomous Database.

Interestingly, I’ve used this solution previously as a demo for a couple of my talks as a Java Developer Evangelist at Oracle.

There are a couple of interesting key takeaways:

You will learn how to access an Oracle Autonomous Database using the Micronaut framework with Micronaut Data.

You will learn how to use Micronaut, AOT and GraalVM to achieve optimal startup times and performance with native executables.

Time to hack, isn’t it? Let’s do it!

A few things about Micronaut Data

Micronaut Data is a database access toolkit that uses Ahead of Time (AOT) compilation to pre-compute queries for repository interfaces. A thin, lightweight runtime layer executes those queries. That’s a killer feature if positioned in combination with GraalVM!

Micronaut Data JDBC is a Micronaut extension, part of the Micronaut Data project, which comprises other options like Reactive, JPA, and so on. However, Micronaut Data JDBC focuses on data access and persistence using the Java Database Connectivity (JDBC) API.

It provides a simple and efficient way to access relational databases. It is built on JDBC and offers several features that make it easy to use, as listed below.

  • Simplified Database Access: Micronaut Data JDBC simplifies database access by reducing the boilerplate code typically required for JDBC-based data access.
  • Query generation: Micronaut Data JDBC uses Ahead-of-Time (AOT) compilation to pre-compute queries for repository interfaces. In practical terms, your queries s are executed more efficiently at runtime and eliminate the need for a runtime meta-model. Besides, a great benefit is catching many database-related issues early in the development process with the support of annotation processors.
  • Query Methods: You can define query methods in your repository interfaces by following naming conventions, and Micronaut Data will generate SQL queries based on these method names.
  • Custom Queries: While query methods based on naming conventions are powerful, you can also write custom SQL queries when needed, which gives you complete flexibility concerning the data model.
  • Entity Management System: It provides an entity management system with the usual features. It allows you to define your data model as Java classes and annotate them with relevant metadata, such as @Entity.
  • Transaction management: Micronaut Data JDBC provides automatic transaction management, simplifying code and reducing the risk of errors.
  • Validation: Micronaut Data JDBC supports Hibernate Validator, which makes it easy to validate data as a usual requirement.
  • Reactive support: Micronaut Data JDBC supports reactive programming, which makes it easy to write non-blocking database applications that can assimilate a couple of exciting options provided by Oracle. With a reactive-friendly API, you can use the Oracle R2DBC Driver or the Oracle Reactive Streams Ingestion Library, to name a few options.
  • Support for Oracle Databases: Micronaut Data JDBC supports using the Oracle Database so that you can configure the database connection properties in your application configuration quickly and straightforwardly.
  • Repository Pattern: Micronaut Data promotes using the repository pattern, where you define interfaces with method signatures for database operations. The framework then generates the implementation of these interfaces.

Project -Java Micronaut Data, GraalVM, and the Oracle Database

First, as a pre-requirement, you must have the Micronaut CLI installed and working properly as expected.

If you’re using Windows, it can be easily installed with Chocolatey.

choco install micronaut --version=4.5.1

Run the command below to confirm the installed Micronaut version.

mn --version
Micronaut Version: 4.5.1

Then, you will proceed to create a Micronaut application written in Java with Micronaut Micronaut Data to access an Oracle Autonomous Database running on the Oracle Cloud Infrastructure.

Proceed to your preferred directory and run the command below.

cd <YOUR_WORKSPACE>\micronaut-graalvm
mn create-app com.oracle.dev.jdbc.micronaut-guide --build=maven --lang=java --jdk=21 --features=data-jdbc,flyway,oracle-cloud-atp,testcontainers

It will create your Micronaut application as expected. Feel free to import it into your preferred Java IDE. Nevertheless, the full project is already available for you as a code sample, please use it from now onwards.

I’m using Java in Visual Studio Code this time, just to test the Micronaut Launch extension created by Oracle.

Just navigate to your project’s home directory and start VS Code as below.

cd <YOUR_WORKSPACE>\micronaut-graalvm\micronaut-guide
code .

Nevertheless, below is an example of how to generate the Eclipse files with Maven for your reference.

cd <YOUR_WORKSPACE>\micronaut-graalvm\micronaut-guide
mvn eclipse:eclipse

Second, we’ll provision an Oracle Autonomous Database instance with Terraform. The Terraform files (*.tf) are located under the terraform/adb-standard directory as shown below per your project’s workspace directory.

<YOUR_WORKSPACE>\micronaut-graalvm\micronaut-guide\src\terraform\adb-standard
Terraform scripts

Navigate to the location. You must edit the files to provide the 3 (three) minimum required inputs as usual: OCI Compartment, Oracle DB ADMIN’s password (defined by you), and your email address.

OCI user’s details — Oracle Autonomous Database provisioning with Terraform

Save the files, and then run the Terraform scripts to provision the database as required.

Initialize Terraform:

cd <YOUR_WORKSPACE>\micronaut-graalvm\micronaut-guide\src\terraform\adb-standard
terraform init
terraform plan
terraform apply

You will receive the usual notification from the Oracle Cloud as soon as your database instance is provisioned successfully.

Oracle Autonomous Database — ATP instance created

Using the OCI Console, navigate to the Oracle Autonomous Database ATP instance you just created, copy its OCID as shown below, and save it. You will need it to configure the database connection in the application.properties file.

ADB ATP instance — copy its OCID

Next, click the Database connection button highlighted in the screenshot below.

ADB ATP instance — Database connection button

Next, scroll down to the Download client credentials (Wallet) section, as shown below, and click the Download wallet button.

Download client credentials (Wallet)

Finally, specify a password for your wallet, provide it again to reconfirm it, and click the Download button.

Download wallet — password

Save your wallet file to your preferred file directory for Oracle ADB Wallets. An example file name is Wallet_MICRONAUTDEMO.zip.

Micronaut — Java implementation

Open the project with VS Code. As explained previously, you will see the Java packages along with a resources directory with some relevant configuration files.

Let’s do a quick recap on the software architectural components of a typical Micronaut application. The project components are organized as shown below.

We have the usual Java packages for our Micronaut Application (entry point), controllers, domain classes, and repository interfaces.

Besides, the resources directory has the relevant files that we’ve used to configure the Micronaut application to connect to the Oracle Autonomous Database.

The directory with the Terraform scripts is also shown below.

Micronaut Java — Project structure

Let’s have a quick walkthrough and visit the packages and the related Java components, with a few comments about the important things on each of them.

com.oracle.dev.jdbc.micronaut

This package has the main class Application.java and a simple data populator to add some initial database records with DataPopulator.java. There are no tricks here, just business-as-usual classes.

com.oracle.dev.jdbc.micronaut.controller

As expected per the design pattern, the controller package has our simple controller component with the expected annotations for Micronaut.

That’s our ThingsController.java, and it has the usual @Controller(“/things”) annotation to support my things retriever, and a few @Get annotations to make it a REST endpoint as usual.

com.oracle.dev.jdbc.micronaut.domain

The domain package has my entity, as we can anticipate, and our Things.java class with the relevant annotations again, but now in the scope of data persistence and Micronaut Data. So we have @MappedEntity and @Id as usual tags when working with ORM and entities, and so on.

com.oracle.dev.jdbc.micronaut.repository

Now, the repository interface is minimal but provides powerful support and features concerning the overall ORM mapping and query capabilities.

Again, here, there are no tricks, just the usual annotations for use with repositories such as @JdbcRepository.

Additional Micronaut features

Lastly, note that the Micronaut application you’ve created with the Micronaut CLI and the command line below has some initial features added to it. Check the features added with the CLI switch — features=data-jdbc,flyway,oracle-cloud-atp,testcontainers

So you get a glimpse of your application's features: Micronaut Data JDBC, Flyway, Oracle Cloud ATP (for the OCI side of it), and Testcontainers.

mn create-app com.oracle.dev.jdbc.micronaut-guide --build=maven --lang=java --jdk=21 --features=data-jdbc,flyway,oracle-cloud-atp,testcontainers

You can use the Micronaut Launcher to get a glimpse of the supported features — https://micronaut.io/launch/ — just use the button below.

Micronaut features

Micronaut Data configuration

You have plenty of options for configuring your application. You can use YAML or a properties file. We’ll use an application properties file. Below is an example with the relevant details you must provide.

Just check the files below and make your choice.

application.properties

At last, note that the above file uses Micronaut Flyway to populate the target database table for you, so you do not have to execute any SQL statements at all, it will automatically do it to add the sample data for you.

Nevertheless, the related SQL script can be found under the /resource/db/migration directory, as shown below.

V1.0.0__create_thing_table.sql

A first run with VS Code only and the JIT (C2) compiler

Our application is now finished and ready to be executed.

We can give it a try by going to VS Code and selecting the menu options Run -> Run Without Debugging options on Visual Studio Code.

Otherwise, you may prefer to compile, build, and run it with Maven from the command-line.

mvn clean package -DskipTests=true
mvn mn:run

The Micronaut application will be launched and after a few seconds, you will be able to access it. Note that this time we’re just running a Java application with Maven and the JVM JIT compiler (C2).

Interestingly, you will be able to see the records that were inserted by the DataPopulator.java class as a startup process, as we defined it.

Open a web browser and navigate to http://localhost:8080/things/

You will see a JSON response as below.

JSON response — Micronaut Data application retrieved the records from the Oracle Database

Now we can proceed to work with GraalVM and generate our native executable!

Native image with GraalVM

Given that, we’ll be able to use GraalVM to create a native executable for our application.

I’m using GraalVM JDK 21 on Windows, so there are a few documented steps to follow to make it work properly.

Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21+35.1

In a nutshell, you have to install the Visual Studio Build Tools. Do not forget that it has to match the details of your underlying hardware platform!

Then, use a specialized CMD prompt (shell) called x64 Native Tools Command Prompt when running commands from the CLI (CMD) that will require GraalVM and the native-image command.

I won’t go into all the details of the previous installations as they’re vastly documented; you can check the official technical resources provided by the GraalVM project.

x64 Native Tools Command Prompt

Run the following commands.

cd <YOUR_WORKSPACE>\micronaut-graalvm\micronaut-guide
mvn package -Dpackaging=native-image

The native compilation process will start and take a few minutes to complete. Meanwhile, you might want to read about Native Image.

After reading about Native Image, you can now understand that the process is quite elaborate, with many steps and verifications to be performed. The screenshot below provides a glimpse of it.

mvn package -Dpackaging=native-image

Run and test your Microservice now with GraalVM

You will see another message with a confirmation that your native executable file has been generated.

All right, so let’s test our microservice! The last step is to find and run the native executable file and execute it. On Windows, it will be delivered as a .exe file, so we can just navigate to the \target directory to find the executable for our application — micronaut-guide.exe.

cd <YOUR_WORKSPACE>\micronaut-graalvm\micronaut-guide\target

Run it now, just double-click the executable file — micronaut-guide.exe!

You will notice that it has a faster startup time, among many things.

io.micronaut.runtime.Micronaut — Startup completed in 8213ms. Server Running: http://localhost:8080

I will leave such exploration as a gift for you and an exercise so you can proceed to learn more about combining all these fantastic technologies — GraalVM, Micronaut Data, and the Oracle Autonomous Database. I hope you enjoyed this blog post! Stay tuned!!!

References

Develop Java applications with Oracle Database

Micronaut.io

Micronaut — 4.5.1

Micronaut Data

Micronaut Data — GitHub

Product — Oracle Database 23ai Free

Developers Guide For Oracle JDBC on Maven Central

Oracle Developers and Oracle OCI Free Tier

Join our Oracle Developers channel on Slack to discuss Java, JDK, JDBC, GraalVM, Microservices with Spring Boot, Helidon, Quarkus, Micronaut, Reactive Streams, Cloud, DevOps, IaC, and other topics!

Build, test, and deploy your applications on Oracle Cloud — for free! Get access to OCI Cloud Free Tier!

--

--