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

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 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:

  • A Dockerfile which can be used to construct the native image.

build.gradle
compileOnly "com.oracle.substratevm:svm"
runtime "io.micronaut:micronaut-graal"

Creating native image

Building Graal native image
$ ./gradlew assemble
$ docker build . -t complete

The previous command will create the image complete:latest. To execute it:

Executing the native image
$ docker run --network host complete
10:29:46.845 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 12ms. Server Running: http://nobita:8080

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

We use the option --network host to use the same network as the host and expose automatically all the ports

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.