Oracle GraalVM AOT機能でNative Imageを作成する。

こんにちは！
日本オラクルJavaチームで、Javaの魅力をお伝えしているエバンジェリストの西川です。

本日は、Cloud Native環境に最適なNative Imageを次世代JDK（GraalVM）で構築して、展開してみたいと思います。

＜はじめに＞ 
・実は、２年前にも似た様な記事を書きました。
https://qiita.com/Oracle_Java_Nishikawa/items/9a78a963e3f9d4e6c406
ただ、こちらの記事では、GraalVM AOT機能を使って、①ネイティブイメージを作成して、②Dockerコンテナ化をする　と言う手順です。（環境はUbuntuサーバ。）

・しかしながら、今回はもっとシンプルに、Windows PCでNative Imageを作成して、Windows上で動かすのみとします。（Native Image作成だけが目的です。よりシンプルです。）

・尚、今回はWindows環境での手順を示しますが、Mac M1や、Linux(OracleLinux９やUbuntu20）でも、動作確認はできております。よって、環境の異なる方は、読み替えてください。

＜所感＞
WindowsでのGraalVM実行環境構築は、MacやLinuxよりも難しいです。
MacやLinuxでは、コマンド一発で環境構築は完了しますが、Windowsでは、Visual Baic Toolsをインストールしないといけません。
この手順の詳細は、こちらに書いてあります。
https://docs.oracle.com/cd/F44923_01/jdk/20/docs/getting-started/installation-windows/#start-using-native-image

＜環境設定＞
1. 上述の様に、Visual Basic Toolsをインストールしてください。
青丸で囲んだ４つのコンポーネントが必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634867/be39bc28-eba8-4b11-ad58-07a248c59022.png)
私は、このVisual Basic Toolsの設定で、つまづきました。（普段は、Mac使いなので。）

2. Oracle GraalVMのインストール
ここから、DLできます。
https://www.oracle.com/jp/downloads/graalvm-downloads.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634867/281f2cf8-0cfe-466a-b7e3-77830fedc27e.png)


3. PATHとJAVA_HOMEの設定をします。
設定後は、こんな感じです。
```
C:\>echo %Java_Home%
\Users\user\oracle\graalvm-jdk-17.0.14+8.1
C:\>
C:\>echo %PATH%
C:\Users\user\oracle\graalvm-jdk-17.0.14+8.1\bin
C:\>
```

＜Native Image構築＞
1）
今回は、Springbootアプリを使用します。
Springboot Initializerで、Springbootアプリを作成。
https://start.spring.io/
デフォルトで良いですが、Dependaciesのところだけ、Spring WebとSpring Boot Actuatorを選んで下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634867/c8452486-4701-4040-a609-87573c55f32a.png)

2）
アプリを開発する。
上で作成したSpringbootアプリを開発ツールで開いて下さい。（下記は、開発ツールとして、IntelliJを利用。尚、Intellijは、コミュニティ版なら無料DL可能です。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634867/00277747-a03e-492c-9fd4-3837ba1dba9d.png)

左ペインに記載されている様に、com.example.com直下に、GraalVMController.javaを作成します。
demo\src\main\java\com\example\demo

```Java:GraalVMController.java
package com.example.demo;  
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;  
@RestController 
@RequestMapping("/") public class GraalVMController {

    @GetMapping("/java")     
    public String sayHello() {
        return "Hello, Oracle GraalVM AOT is best choice for cloud native solution!";
    } 
} 
````
変更を加えるのは、上だけです。

３）
Native Imageをビルドします。
ビルドコマンドは下記。（ビルドに時間は掛かります。環境によりますが、数分程度。）
```java:cmd
C:\Users\user\Downloads\demo\demo>./gradlew clean nativeCompile
```
＜起動＆確認＞
ビルドが終わったら、起動します。
実行ファイルは、demo\build\native\nativeCompileの直下に作成されております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634867/94698170-0c75-4014-945b-9e67f883d82a.png)

実行します。
```java:cmd
PS C:\Users\user\Downloads\demo\demo\build\native\nativeCompile> ./demo

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.4.3)

2025-02-28T17:10:20.944+09:00  INFO 6048 --- [demo] [           main] com.example.demo.DemoApplication         : Starting AOT-processed DemoApplication u
sing Java 17.0.14 with PID 6048 (C:\Users\user\Downloads\demo\demo\build\native\nativeCompile\demo.exe started by user in C:\Users\user\Downloads\demo\demo\build\native\nativeCompile)
2025-02-28T17:10:20.944+09:00  INFO 6048 --- [demo] [           main] com.example.demo.DemoApplication         : No active profile set, falling back to 1 default profile: "default"
2025-02-28T17:10:20.992+09:00  INFO 6048 --- [demo] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2025-02-28T17:10:20.992+09:00  INFO 6048 --- [demo] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-02-28T17:10:20.992+09:00  INFO 6048 --- [demo] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.36]
2025-02-28T17:10:20.992+09:00  INFO 6048 --- [demo] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-02-28T17:10:21.007+09:00  INFO 6048 --- [demo] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 63 ms
2025-02-28T17:10:21.038+09:00  WARN 6048 --- [demo] [           main] i.m.c.i.binder.jvm.JvmGcMetrics          : GC notifications will not be available because no GarbageCollectorMXBean of the JVM provides any. GCs=[young generation scavenger, complete scavenger]
2025-02-28T17:10:21.038+09:00  INFO 6048 --- [demo] [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint beneath base path '/actuator'
2025-02-28T17:10:21.051+09:00  INFO 6048 --- [demo] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2025-02-28T17:10:21.051+09:00  INFO 6048 --- [demo] [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.122 seconds (process running for 0.138)
```


この状態で、Command Promptを起動して、実行します。
http://localhost:8080/java

```java:cmd
C:\Users\user\Downloads\demo\demo>
C:\Users\user\Downloads\demo\demo>curl http://localhost:8080/java
Hello, Oracle GraalVM AOT is best choice for cloud native solution!
C:\Users\user\Downloads\demo\demo>
```

以上です。

P.S. 普段は、MacやLinuxで構築運用しているので、Windowsでは初めてでした。
Windowsの方が、手順が多くて、GraalVM AOT環境の設定は難しいかもですね。


ご不明な点がございましたら、お気軽にお問い合わせください。