Creating your first Micronaut Graal application

Learn how to create a Hello World Micronaut Graal application.

Authors: Iván López, Sergio del Amo

Micronaut Version: 1.0.0.RC2

1 Getting Started

In this guide we are going to create a Micronaut application with Graal support.

1.1 What you will need

To complete this guide, you will need the following:

  • Some time on your hands

  • A decent text editor or IDE

  • JDK 1.8 or greater installed with JAVA_HOME configured appropriately

1.2 Solution

We recommend you to follow the instructions in the next sections and create the app step by step. However, you can go right to the completed example.

or

Then, cd into the complete folder which you will find in the root project of the downloaded/cloned project.

2 Writing the App

Create an app using the Micronaut Command Line Interface.

mn create-app example.micronaut.complete --features=graal-native-image

The previous command creates a micronaut app with the default package example.micronaut in a folder named complete and with support for Graal.

If you are using Java or Kotlin and IntelliJ IDEA make sure you have enabled annotation processing.

annotationprocessorsintellij

3 Service

Create a POJO Conference.java:

src/main/java/example/micronaut/Conference.java
package example.micronaut;

public class Conference {
    private String name;

    public Conference(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Create a Service:

src/main/java/example/micronaut/ConferenceService.java
package example.micronaut;

import javax.inject.Singleton;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

@Singleton (1)
public class ConferenceService {

    private static final List<Conference> CONFERENCES = Arrays.asList(
            new Conference("Greach"),
            new Conference("GR8Conf EU"),
            new Conference("Micronaut Summit"),
            new Conference("Devoxx Belgium"),
            new Conference("Oracle Code One"),
            new Conference("CommitConf"),
            new Conference("Codemotion Madrid")
    );

    public Conference randomConf() { (2)
        return CONFERENCES.get(new Random().nextInt(CONFERENCES.size()));
    }
}
1 Use javax.inject.Singleton to designate a class a a singleton.
2 Return a random conference.

4 Controller

Create a Controller with a method that returns a Conference. Micronaut will convert it automatically to JSON in the response:

src/main/java/example/micronaut/ConferenceController.java
package example.micronaut;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller("/conferences") (1)
public class ConferenceController {

    private final ConferenceService conferenceService;

    public ConferenceController(ConferenceService conferenceService) { (2)
        this.conferenceService = conferenceService;
    }

    @Get("/random") (3)
    public Conference randomConf() { (4)
        return conferenceService.randomConf();
    }
}
1 The class is defined as a controller with the @Controller annotation mapped to the path /conferences.
2 Constructor injection
3 The @Get annotation is used to map the index method to all requests that use an HTTP GET
4 Return a Conference.

5 Adding Graal support

GraalVM is a new universal virtual machine from Oracle that supports a polyglot runtime environment and the ability to compile Java applications down to native machine code.

Any Micronaut application can be run using the GraalVM JVM, however special support has been added to Micronaut to support running Micronaut applications using GraalVM’s nativeimage tool.

Use of GraalVM’s nativeimage tool is only supported in Java or Kotlin projects. Groovy relies heavily on reflection which is only partially supported by GraalVM.

5.1 Installing Graal

To start using GraalVM you should first install the GraalVM SDK via the Getting Started instructions or using SDKman:

Installing GraalVM 1.0.0-rc7 with SDKman
$ sdk install java 1.0.0-rc7-graal
$ sdk use java 1.0.0-rc7-graal

Note the above commands install the 1.0.0-rc7 version, and may need to be altered depending on the current release available.

As of this writing, GraalVM is currently only available for Linux and Mac OS X systems.

Once you have installed the SDK you should make the svm dependency available via your local Maven cache. The easiest way to do this is via Maven’s install command:

Installing the SVM Dependency Locally
$ mvn install:install-file -Dfile=${JAVA_HOME}/jre/lib/svm/builder/svm.jar \
                           -DgroupId=com.oracle.substratevm \
                           -DartifactId=svm \
                           -Dversion=GraalVM-1.0.0-rc7 \
                           -Dpackaging=jar
If you don’t have Maven available you can install it using SDKMan: sdk install maven

5.2 Creating Graal native image

When we created the application we used the graal-native-image feature. This feature adds three important items:

  • A MicronautSubstitutions.java file needed to recompute Netty and Caffeine’s use of Unsafe.

  • svm and graal dependencies in build.gradle:

build.gradle
    compileOnly "com.oracle.substratevm:svm:GraalVM-1.0.0-rc7"
    runtimeOnly "io.micronaut:graal"
  • A build-native-image.sh bash script which can be used as a template to construct the native image.

Creating native image

To create the native image the only thing we need to do is execute the build-native-image.sh script. The script will build the application fat-jar, generate the reflect.json file and build the native image.

Building native image
complete $ ./build-native-image.sh

A native image named complete will be generated. Once the native image is created we can start it:

Executing the native image
complete $ ./complete
11:20:28.881 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 14ms. Server Running: http://localhost:8080

We can see that the application starts in only 14ms.

Sending a request

You can run a few cURL requests to test the application:

complete $ time curl localhost:8080/conferences/random
{"name":"Oracle Code One"}
real    0m0.016s
user    0m0.005s
sys     0m0.004s

complete $ time curl localhost:8080/conferences/random
{"name":"GR8Conf EU"}
real    0m0.014s
user    0m0.005s
sys     0m0.004s

6 Next steps

Read more about Graal Support inside Micronaut.