-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move Micronaut demos under native-image/microservices; Add Gradle dem…
…o sources; Sycnhronize READMEs
- Loading branch information
Showing
33 changed files
with
2,003 additions
and
0 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
native-image/microservices/micronaut-hello-rest-gradle/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
Thumbs.db | ||
.DS_Store | ||
.gradle | ||
build/ | ||
target/ | ||
out/ | ||
.micronaut/ | ||
.idea | ||
*.iml | ||
*.ipr | ||
*.iws | ||
.project | ||
.settings | ||
.classpath | ||
.factorypath |
115 changes: 115 additions & 0 deletions
115
native-image/microservices/micronaut-hello-rest-gradle/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# Micronaut REST Application Using Gradle and GraalVM Native Image | ||
|
||
This example shows how to run a simple [Micronaut](https://micronaut.io/) REST application, compile it with [GraalVM Native Image](https://www.graalvm.org/reference-manual/native-image/), and package it in a container image. | ||
Along the way you will see the performance benefits that GraalVM Native Image provides to Micronaut applications. | ||
|
||
## Preparation | ||
|
||
1. Download and install GraalVM using [SDKMAN!](https://sdkman.io/): | ||
```bash | ||
sdk install java 21.0.5-graal | ||
``` | ||
> Note: A Java version between 17 and 21 is required to execute Gradle (see the Gradle Compatibility Matrix). | ||
|
||
2. Download or clone GraalVM demos repository and navigate into the example directory: | ||
```bash | ||
git clone https://github.com/graalvm/graalvm-demos | ||
``` | ||
```bash | ||
cd graalvm-demos/native-image/microservices/micronaut-hello-rest-gradle | ||
``` | ||
|
||
## Compile and Run from a JAR File | ||
|
||
1. Compile the application and build a fat JAR that includes all its dependencies: | ||
```bash | ||
./gradlew assemble | ||
``` | ||
|
||
2. Run the application on HotSpot from a JAR file: | ||
```bash | ||
java -jar build/libs/hello-0.1-all.jar | ||
``` | ||
You can see the app starts in few hundred milliseconds. | ||
|
||
3. To test the `HelloController` you created, either `curl http://localhost:8080/hello` or open it in a browser: | ||
```bash | ||
curl http://localhost:8080/hello | ||
``` | ||
|
||
The response should be `Example Response`. | ||
Then stop the application: | ||
``` | ||
CTRL-C | ||
``` | ||
|
||
## Build and Run a Native Executable | ||
|
||
With no runtime reflection, Micronaut is extremely well suited to ahead-of-time (AOT) compilation with [GraalVM Native Image](https://www.graalvm.org/latest/reference-manual/native-image/). | ||
Mironaut provides support for GraalVM Native Image by default. | ||
|
||
1. Compile this REST application ahead of time with Gradle: | ||
```bash | ||
./gradlew nativeCompile | ||
``` | ||
|
||
Compilation can take a few minutes, but more cores and more memory reduce the required time. | ||
|
||
The result is a standalone executable placed in the _build/native/nativeCompile/_ directory named `MnHelloRest`. | ||
|
||
2. Run the application from the native executable: | ||
```bash | ||
./build/native/nativeCompile/MnHelloRest | ||
``` | ||
This ahead-of-time compiled application started much faster than when running on HorSpot! | ||
|
||
It is so fast because it does not have to parse bytecode for JDK and application classes, initialize the JIT compiler, allocate JIT code caches, JIT profile data caches, and so on. | ||
The startup is negligible. | ||
|
||
## Containerize and Run in Docker on Linux | ||
|
||
If you are on Linux, you can easily create a Docker container image that includes the native Linux executable you have built. | ||
For Windows or macOS, the process is little different and is not covered here. | ||
|
||
Typically, the first question is what base image to use? | ||
GraalVM Native Image supports both static and dynamically linked executables, with dynamic being the default. | ||
Your native executable is dynamically linked against `glibc`, you will need a base image that includes it. | ||
One of the smallest base images you could use is Alpine Linux with `glibc`. | ||
|
||
1. Create a `Dockerfile` with the following contents: | ||
```Dockerfile | ||
FROM frolvlad/alpine-glibc:alpine-3.12 | ||
EXPOSE 8080 | ||
ADD build/native-image/application /app/example | ||
ENTRYPOINT ["/app/example"] | ||
``` | ||
|
||
Simply copy the native executable into the container image and expose port 8080. | ||
|
||
2. Build a container image: | ||
```bash | ||
docker build . -t example | ||
``` | ||
|
||
The container image that was created is about 94MB, which makes sense because the Alpine with `glibc` base image is about 18MB and your application is about 71MB. | ||
```bash | ||
docker images | ||
``` | ||
```sh | ||
REPOSITORY TAG IMAGE ID CREATED SIZE | ||
hello latest f5ea290d8d08 2 seconds ago 94.2MB | ||
``` | ||
|
||
3. You can run the container image and the application directly: | ||
```bash | ||
docker run -p8080:8080 --rm hello | ||
``` | ||
```bash | ||
curl http://localhost:8080/hello | ||
``` | ||
It will return the same message "Example Response". | ||
|
||
### Wrapping Up | ||
|
||
Micronaut makes it really easy to build modern Java applications and microservices. | ||
Its elimination of runtime reflection also makes it an ideal application framework to use with GraalVM Native Image for ahead-of-time compilation and containerization. |
40 changes: 40 additions & 0 deletions
40
native-image/microservices/micronaut-hello-rest-gradle/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
plugins { | ||
id("com.github.johnrengelman.shadow") version "7.1.2" | ||
id("io.micronaut.application") version "3.7.0" | ||
} | ||
|
||
version = "0.1" | ||
group = "hello" | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
annotationProcessor("io.micronaut:micronaut-http-validation") | ||
implementation("io.micronaut:micronaut-http-client") | ||
implementation("io.micronaut:micronaut-jackson-databind") | ||
implementation("jakarta.annotation:jakarta.annotation-api") | ||
runtimeOnly("ch.qos.logback:logback-classic") | ||
implementation("io.micronaut:micronaut-validation") | ||
|
||
} | ||
|
||
|
||
application { | ||
mainClass.set("hello.Application") | ||
} | ||
java { | ||
sourceCompatibility = JavaVersion.toVersion("17") | ||
targetCompatibility = JavaVersion.toVersion("17") | ||
} | ||
|
||
graalvmNative.toolchainDetection = false | ||
micronaut { | ||
runtime("netty") | ||
testRuntime("junit5") | ||
processing { | ||
incremental(true) | ||
annotations("hello.*") | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
native-image/microservices/micronaut-hello-rest-gradle/gradle.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
micronautVersion=3.8.2 |
Oops, something went wrong.