ネイティブイメージは、Java のアプリをビルドの時点で機械語の実行ファイルにする方法です。 起動が速く、メモリも少なくてすみます。そのかわり、ビルドに数分と1GB 以上のメモリがかかり、「実行時にクラスやプロファイルを切り替える」ような動的な使い方に制約が付きます。Spring Boot 4.1.1 では、Gradle なら org.graalvm.buildtools.native プラグインを足して gradle nativeCompile、Maven なら mvn -Pnative native:compile で作れます。

GraalVM CE 25.0.2 で、Spring を使わない小さな HTTP サーバー(JDK の HttpServer)を JVM とネイティブで動かして比べた結果です(5回の中央値)。

項目 JVM(OpenJDK 25.0.4) ネイティブイメージ
起動から最初の応答まで 333ms 10ms
最初の応答のあとのメモリ(RSS) 56.7MB 17.5MB
200回応答したあとのメモリ(RSS) 70.3MB 44.0MB
配るもの jar(数 KB)+ JDK 実行ファイル 1 つ(15.93MB)
ビルド時間 数秒(javac) 1分37秒〜2分49秒
ビルド中の最大メモリ — 1.17〜1.18GB

確認環境:GraalVM CE 25.0.2(native-image 25.0.2、Linux x64、2 CPU・メモリ 7GB)で、上の小さなプログラムを実際にビルドして、起動時間・メモリ(/proc の VmRSS)・ビルド時間・リフレクションのエラーと直し方を確かめました。JVM 側は OpenJDK 25.0.4.1 と、GraalVM 付属の JVM で動かしています。Spring Boot の手順・制約・AOT の生成物は Spring Boot 4.1.1 のリファレンスとソース(v4.1.1 のタグ)で、RuntimeHints の API は Spring Framework v7.0.9 のソースで確かめました(確認日 2026年10月13日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Spring BootのGraalVMネイティブイメージ|作り方と制約」

向いている・向いていない

使いどころ 向き 理由
サーバーレス(AWS Lambda など)・すぐ止めるジョブ ◎ 起動の速さがそのまま待ち時間・料金に効く
台数をすばやく増減するコンテナ ○ 起動が速く、1台あたりのメモリが少ない
コマンドラインのツール ◎ JDK を入れずに1ファイルで配れる
ずっと動かす高負荷の API △ JVM は動きながら最適化(JIT)するので、長く動かすと速くなる
実行時にプラグイン・クラスを差し替える × クラスパスはビルド時に固定される
開発中に何度もビルドし直す × 1回のビルドに数分かかる

Lambda の起動を速くする方法の比較は、関連記事「Lambdaコールドスタート対策|SnapStartとプロビジョンド同時実行の比較」で扱っています。JVM のままで起動を速くする方法(AOT キャッシュ)は、関連記事「Spring Boot Dockerfile|コピペ用全文とAOTキャッシュ設定」で扱っています。

何が起きているか:AOT と「閉じた世界」

Spring Boot のリファレンス(4.1.1)では、JVM との違いとして次のものが挙げられています。

  • ビルドの時点で、main からたどれるコードだけを調べ、たどれないコードは実行ファイルに入らない
  • GraalVM はコードの動的な部分(リフレクション・リソース・シリアライズ・動的プロキシ)を自分では見つけられず、教える必要がある
  • クラスパスはビルド時に固定され、変えられない
  • 遅延読み込みは無く、実行ファイルに入ったものは起動時にメモリに読まれる

これを「閉じた世界(closed-world)」の前提と呼びます。Spring は、この前提に合わせるために、ビルド時に AOT 処理(Ahead-of-Time 処理、実行前の下ごしらえ)を行います。

AOT 処理で作られるもの 中身 置き場所(Gradle)
Java のソース @Configuration を読んで作った Bean 定義(MyConfiguration__BeanDefinitions など) build/generated/aotSources
バイトコード CGLIB のプロキシなど build/generated/aotClasses
GraalVM 用のヒント(JSON) リフレクション・リソース・シリアライズ・プロキシ・JNI META-INF/native-image/{groupId}/{artifactId}/

Maven の場合は target/spring-aot/main/sources・target/spring-aot/main/classes です。実行時に @Configuration を読んで Bean を組み立てる処理を、ビルド時に済ませておくので、起動が速くなります。

作り方

前提

必要なもの 内容
GraalVM(native-image 付き) JDK 25 版。Boot のドキュメントでは Liberica Native Image Kit 25 が例に挙がっている
C コンパイラ Linux は gcc と zlib の開発用ファイル。Windows は Visual Studio Build Tools と Windows SDK
メモリ 手元のビルドでは最大 1.18GB 使った(下の実測)
Buildpacks で作る場合 Docker と JDK 25 以上。ローカルの GraalVM は不要

native-image はクロスコンパイルができません(Boot のドキュメント)。Linux 用の実行ファイルは Linux で、macOS 用は macOS でビルドします。

Gradle

// build.gradle.kts
plugins {
    java
    id("org.springframework.boot") version "4.1.1"
    id("io.spring.dependency-management") version "1.1.7"
    id("org.graalvm.buildtools.native") version "1.1.8"
}

java {
    toolchain { languageVersion = JavaLanguageVersion.of(25) }
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-webmvc")
    testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
}
./gradlew nativeCompile                     # 実行ファイルを作る
./build/native/nativeCompile/myproject      # 動かす
./gradlew nativeTest                        # テストをネイティブで動かす
./gradlew bootBuildImage                    # Buildpacks でコンテナイメージにする(Docker が必要)

1.1.8 は、Spring Boot v4.1.1 のソース(gradle.properties の nativeBuildToolsVersion)で使われている Native Build Tools の版です。org.graalvm.buildtools.native プラグインを入れると、Boot の Gradle プラグインが AOT 処理のタスク(processAot)を自動で組み込みます。

Maven

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.1.1</version>
</parent>

<build>
    <plugins>
        <plugin>
            <groupId>org.graalvm.buildtools</groupId>
            <artifactId>native-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
mvn -Pnative native:compile         # target/myproject ができる
mvn -PnativeTest test               # テストをネイティブで動かす
mvn -Pnative spring-boot:build-image  # Buildpacks でコンテナイメージにする

spring-boot-starter-parent の native プロファイルは、ドキュメントでは「process-aot の実行」「Native Build Tools の既定値(実行可能 jar ではなくクラスパスを使う、GraalVM の版の確認、サードパーティの到達可能性メタデータのダウンロード)」をまとめて設定します。Maven の基本は、関連記事「Mavenコマンド一覧|pom.xml書き方とよく使うオプション」で扱っています。

ネイティブにする前に JVM で確かめる

ビルドに数分かかるので、AOT で作ったコードを JVM で先に動かして、Bean の構成が正しいかを確かめると早く進みます。

mvn -Pnative package
java -Dspring.aot.enabled=true -jar target/myproject-0.0.1-SNAPSHOT.jar

Boot のドキュメントでは、spring.aot.enabled=true で起動できれば「ネイティブにしても動く見込みが高くなる」と説明されています。ログには Starting AOT-processed MyApplication と出ます。

実測:ビルドの時間とメモリ

GraalVM CE 25.0.2 で、Spring を使わない小さなプログラム(JDK の HttpServer で JSON を返す、クラス2つ)を native-image -jar app.jar でビルドしたログの要点です。

[1/8] Initializing...                    (10.2s @ 0.11GB)
 Java version: 25.0.2+10, vendor version: GraalVM CE 25.0.2+10.1
 Graal compiler: optimization level: 2, target machine: x86-64-v3
 C compiler: gcc (linux, x86_64, 13.3.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
Build resources:
 - 4.74GB of memory (75.6% of system memory, in container)
 - 2 thread(s) (100.0% of 2 available processor(s), determined at start)
[2/8] Performing analysis...  [*****]    (54.9s @ 0.44GB)
    3,771 types,   4,434 fields, and  17,148 methods found reachable
    1,227 types,      36 fields, and     475 methods registered for reflection
[6/8] Compiling methods...    [******]   (41.2s @ 0.40GB)
  16.90MB in total image size, 15.93MB in total file size
   7.2s (5.8% of total time) in 669 GCs | Peak RSS: 1.18GB | CPU load: 1.42
Finished generating 'app-native' in 2m 3s.
ビルド かかった時間 ビルド中の最大メモリ 実行ファイル
1回目 2分3秒 1.18GB 15.93MB
2回目(コードを足した) 2分49秒 1.18GB 15.93MB
3回目(メタデータを足した) 1分37秒 1.17GB 15.93MB
-Ob(速くビルドする設定) 1分33秒 1.16GB 16.19MB

時間の大半は「解析(たどれるコードを探す)」と「コンパイル」です。この小さなプログラムでも 2 CPU で 1分半〜3分かかり、メモリは 1GB を超えました。 Spring Boot のアプリは依存が多いので、時間とメモリはこれより大きくなります。Boot のドキュメントでも、Docker Desktop(macOS)でビルドするならメモリを 8GB 以上に増やすよう書かれています。CI では、ビルド用のマシンのメモリと時間の上限を先に確かめておきます。

できた実行ファイルは、OS の C ライブラリと zlib だけに依存していました。

$ ldd app-native
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6

実測:起動時間とメモリ

起動してから /hello が最初に応答を返すまでの時間と、そのときのメモリ(RSS、プロセスが実際に使っている物理メモリ)を、5回ずつ測りました。

実行方法 最初の応答まで(5回) 中央値 最初の応答のあとの RSS 200回応答したあとの RSS
OpenJDK 25.0.4 の JVM 571・324・333・337・261ms 333ms 56.7MB 70.3MB
GraalVM 25.0.2 の JVM 431・425・278・488・404ms 425ms 117.1MB 132.8MB
ネイティブイメージ 10・24・9・14・10ms 10ms 17.5MB 44.0MB

起動は約30分の1、起動直後のメモリは約3分の1になりました。 一方で、200回応答したあとの RSS は 44.0MB まで増えました。ネイティブイメージの既定の GC は Serial GC で、ビルドのログでは最大ヒープは「RAM の 80%」です。コンテナで動かすなら、-Xmx を付けて上限を決めておきます(ビルドの推奨にも「HEAP: Set max heap」と出ました)。

Spring Boot のアプリでの数字は、Spring Boot のドキュメントの例では次のように出ています。

 :: Spring Boot ::  (v4.1.1)
........ Started MyApplication in 0.08 seconds (process running for 0.095)

制約の一覧

Spring Boot 4.1.1 のリファレンスと GraalVM の前提から、気をつける点をまとめました。

制約 何が起きるか 対処
@Profile・プロファイル別の設定 AOT 処理の時点の条件で Bean が決まる。実行時にプロファイルを変えても、Bean の有無は変わらない ビルド時にプロファイルを指定する(下)
@ConditionalOnProperty・.enabled の設定 実行時に値を変えても Bean は増減しない ビルド時の値で決める
文字列からクラスを読むリフレクション ClassNotFoundException など(下で再現) RuntimeHints か到達可能性メタデータ
文字列で名前を組み立てるリソース getResourceAsStream が null hints.resources().registerPattern(…)
動的プロキシ(JDK Proxy) 登録されていない組み合わせは作れない hints.proxies().registerJdkProxy(…)
Java のシリアライズ 登録した型だけ registerJavaSerialization
クラスパスの変更 ビルド後に jar を足しても読まれない ビルドし直す
実行時のバイトコード生成・Java エージェント JVM と同じようには使えない(バイトコードを書き換える APM など) ネイティブに対応した計測の方法を選ぶ
ネストした @ConfigurationProperties @NestedConfigurationProperty が無いと値が入らない 注釈を付け、public の getter・setter を用意
クロスコンパイル できない OS・CPU ごとにビルドする

プロファイルの制約は、いちばん気づきにくいものです。 Boot のドキュメントでは、AOT 処理は @Conditional をビルド時の環境で評価し、プロファイルも条件で実装されているので影響を受ける、と説明されています。ビルド時のプロファイルは次のように指定します。

// build.gradle.kts
tasks.withType<org.springframework.boot.gradle.tasks.aot.ProcessAot>().configureEach {
    args("--spring.profiles.active=prod")
}
<!-- pom.xml の native プロファイルの中 -->
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>process-aot</id>
            <configuration>
                <profiles>prod</profiles>
            </configuration>
        </execution>
    </executions>
</plugin>

ドキュメントでは、Bean の条件に関係しない設定値だけを変えるプロファイルは、制約なく使えるとされています。URL やタイムアウトの値を application-prod.yml で変える使い方はそのまま動きます。プロファイルの基本は、関連記事「Spring Bootプロファイル切り替え|application.ymlと優先順位」で扱っています。

再現:リフレクションが見つからない

文字列で受け取ったクラス名を Class.forName で読むコードです。

static void reflect(String className) throws Exception {
    Class<?> c = Class.forName(className);              // 文字列から読む
    Object o = c.getDeclaredConstructor().newInstance();
    System.out.println("reflect: " + c.getMethod("greet").invoke(o));
}

JVM では動き、ネイティブイメージでは同じクラスがあるのに見つかりませんでした。

$ java -jar app.jar reflect app.Greeter
reflect: hello from Greeter

$ ./app-native reflect app.Greeter
Exception in thread "main" java.lang.ClassNotFoundException: app.Greeter
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:327)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:297)
    at java.base@25.0.2/java.lang.Class.forName(DynamicHub.java:1708)
    ...
    at app.App.reflect(App.java:28)

リソースも、名前を実行時に組み立てると入りませんでした。

$ java -jar app.jar resource2 /META-INF/MANIFEST.MF
resource2: Manifest-Version: 1.0

$ ./app-native resource2 /META-INF/MANIFEST.MF
resource2: null(見つからない)

一方、名前を定数で書いたもの(Proxy.newProxyInstance(…, new Class<?>[]{Runnable.class}, …) や getResourceAsStream("/config.properties"))は、何も登録しなくてもネイティブで動きました。GraalVM がビルド時に定数を読み取って登録するためです。問題になるのは、名前が実行時に決まるときです。

直し方1:トレースエージェントで集める

JVM で動かしながら、リフレクションなどの使われ方を記録する「トレースエージェント」があります。

java -agentlib:native-image-agent=config-merge-dir=src/main/resources/META-INF/native-image/app \
     -jar app.jar reflect app.Greeter

GraalVM 25.0.2 では、reachability-metadata.json という1つのファイルに次のように記録されました。

{
  "reflection": [
    { "type": "app.Greeter",
      "methods": [ { "name": "<init>", "parameterTypes": [] },
                   { "name": "greet", "parameterTypes": [] } ] },
    { "type": { "proxy": ["java.util.concurrent.Callable"] } }
  ],
  "resources": [
    { "glob": "META-INF/MANIFEST.MF" }
  ]
}

このファイルを jar の META-INF/native-image/ の下に入れてビルドし直すと、reflect: hello from Greeter と動き、リソースも読めました。登録したぶん、ビルドログの「registered for reflection」が 1,227 types から 1,231 types に増えました。

Boot のドキュメントでは、Spring Boot のアプリなら -Dspring.aot.enabled=true を付けてエージェントを動かし、出てきたファイルを src/main/resources/META-INF/native-image/ に置く手順が示されています。エージェントは「動かした道筋」しか記録しないので、めったに通らない処理(エラー処理など)も動かしておきます。

直し方2:RuntimeHints をコードで書く(Spring)

Spring のアプリでは、RuntimeHintsRegistrar を実装して @ImportRuntimeHints で読み込ませます。Spring Boot のドキュメントの例をもとにした形です。

package com.example.nativeimage;

import java.lang.reflect.Method;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.util.ReflectionUtils;

@Configuration
@ImportRuntimeHints(AppRuntimeHints.Registrar.class)
public class AppRuntimeHints {

    static class Registrar implements RuntimeHintsRegistrar {
        @Override
        public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
            // クラスごと:コンストラクタとメソッドを呼べるようにする
            hints.reflection().registerType(Greeter.class,
                    MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
                    MemberCategory.INVOKE_PUBLIC_METHODS);

            // メソッドを1つだけ
            Method m = ReflectionUtils.findMethod(Greeter.class, "greet");
            hints.reflection().registerMethod(m, ExecutableMode.INVOKE);

            // リソース(パターンで指定)
            hints.resources().registerPattern("templates/mail/*.txt");

            // JDK の動的プロキシ(インターフェースの組み合わせ)
            hints.proxies().registerJdkProxy(PaymentGateway.class);

            // Java のシリアライズ
            hints.reflection().registerJavaSerialization(CartSnapshot.class);
        }
    }
}
登録するもの メソッド 例
クラス(メンバーをまとめて) reflection().registerType(型, MemberCategory…) INVOKE_DECLARED_CONSTRUCTORS など
メソッド1つ reflection().registerMethod(Method, ExecutableMode.INVOKE) 上の例
リソース resources().registerPattern("…") templates/mail/*.txt
動的プロキシ proxies().registerJdkProxy(インターフェース…) 組み合わせごとに1回
シリアライズ reflection().registerJavaSerialization(型) Serializable のクラス
JSON の変換に使うクラス @RegisterReflectionForBinding(型.class) RestClient で受け取る DTO

Spring Framework 7.0 のソースでは、MemberCategory の INTROSPECT_PUBLIC_METHODS・PUBLIC_FIELDS・DECLARED_CLASSES などが @Deprecated(since = "7.0", forRemoval = true) になっています。7.0 で使うのは INVOKE_…(呼べるようにする)と ACCESS_…(フィールドを読み書きできるようにする)の系統です。

@RestController の引数・戻り値の型は、Spring が自動でヒントを作ります。 Boot のドキュメントでは、RestClient・WebClient・RestTemplate を直接使って JSON を受け取る型には、@RegisterReflectionForBinding が必要になることがあると書かれています。

@Service
@RegisterReflectionForBinding({WeatherResponse.class, WeatherResponse.Daily.class})
public class WeatherClient {
    private final RestClient restClient;
    WeatherClient(RestClient.Builder builder) { this.restClient = builder.baseUrl("https://api.example.com").build(); }

    public WeatherResponse today() {
        return restClient.get().uri("/today").retrieve().body(WeatherResponse.class);
    }
}

ヒントをテストする

ビルドに数分かかるので、ヒントの登録は通常の単体テストで先に確かめます。Boot のドキュメントで紹介されている RuntimeHintsPredicates を使います。

class AppRuntimeHintsTests {

    @Test
    void registersHints() {
        RuntimeHints hints = new RuntimeHints();
        new AppRuntimeHints.Registrar().registerHints(hints, getClass().getClassLoader());

        assertThat(RuntimeHintsPredicates.reflection().onType(Greeter.class)).accepts(hints);
        assertThat(RuntimeHintsPredicates.resource().forResource("templates/mail/welcome.txt")).accepts(hints);
        assertThat(RuntimeHintsPredicates.proxies().forInterfaces(PaymentGateway.class)).accepts(hints);
    }
}

AssertJ の書き方は、関連記事「AssertJの使い方|assertThatの早見表(文字列・リスト・例外・日付)」で扱っています。

直し方3:ライブラリのメタデータを使う

自分のコードではなく、ライブラリの中のリフレクションで落ちることもあります。Boot のドキュメントでは、Spring 自体はサードパーティのライブラリ向けのヒントを持たず、GraalVM の到達可能性メタデータのリポジトリ(oracle/graalvm-reachability-metadata)に頼る、と説明されています。Maven の native プロファイルは、このメタデータを自動でダウンロードします。そこにも無ければ、トレースエージェントか RuntimeHints で足します。

よくあるエラー

症状・メッセージ 原因 対処
ClassNotFoundException(JVM では動く) 文字列で読むクラスが登録されていない エージェントか registerType
getResourceAsStream が null リソースが実行ファイルに入っていない registerPattern
MissingReflectionRegistrationError など、登録不足を示すエラー(GraalVM の設定しだいで出る) リフレクションの登録不足 エラーに出た型を登録する
JSON の項目が空・変換できない DTO のリフレクション登録が無い @RegisterReflectionForBinding
本番で別プロファイルの Bean が無い・余る Bean の構成がビルド時のプロファイルで決まった processAot にプロファイルを渡してビルドし直す
ビルドが途中で落ちる・終わらない メモリ不足(手元の小さなプログラムでも最大 1.18GB) ビルドのマシン・Docker のメモリを増やす
native-image が見つからない GraalVM ではない JDK を使っている GraalVM・Liberica NIK を使う
ビルドで C コンパイラのエラー gcc・zlib・Windows の Build Tools が無い 前提の表のものを入れる
macOS で作った実行ファイルが Linux で動かない クロスコンパイルはできない 目的の OS でビルドする(コンテナ・CI)
コンテナでメモリが増え続ける 最大ヒープの既定が「RAM の 80%」 起動時に -Xmx を付ける

よくある質問

Q. JVM とネイティブ、どちらのイメージを使うかはどう決めますか。 A. 起動の速さとメモリが料金・待ち時間に直結するなら(サーバーレス・台数の増減が激しい)ネイティブ、長く動かしてスループットを出す API なら JVM が目安です。ビルド時間と制約の対応にかかる手間も比べます。

Q. Docker のイメージにするにはどうしますか。 A. gradle bootBuildImage・mvn -Pnative spring-boot:build-image で、Buildpacks がネイティブのイメージを作ります。ドキュメントでは、この方法ではローカルに GraalVM は要らず、Docker が必要です。Dockerfile で作る場合は、ビルド用のステージで GraalVM を使い、実行用のステージに実行ファイルだけを入れます。Docker の基本は、関連記事「Dockerfileの書き方|軽く・速く・安全なイメージを作るベストプラクティス」で扱っています。

Q. Boot 3 から 4 に上げると何が変わりますか。 A. Buildpacks を使う場合、Boot 4.1.1 のドキュメントでは JDK 25 以上でビルドする必要があります。Spring Framework 7.0 では MemberCategory の一部が非推奨になりました。移行全体は、関連記事「Spring Boot 4移行の手順|3から4の変更点一覧とチェックリスト」で扱っています。

まとめ

  • 作り方は Gradle:nativeCompile、Maven:-Pnative native:compile。プラグインは org.graalvm.buildtools.native(Boot 4.1.1 は 1.1.8)
  • 小さなプログラムの実測で、起動 333ms → 10ms、起動直後のメモリ 56.7MB → 17.5MB
  • そのかわり、ビルドは 1分半〜3分、ビルド中のメモリは 1.18GB(2 CPU・小さなプログラム)
  • プロファイルと @ConditionalOnProperty はビルド時に決まる。本番のプロファイルは processAot に渡す
  • 名前が実行時に決まるリフレクション・リソースは、トレースエージェントか RuntimeHints で登録する
  • 先に -Dspring.aot.enabled=true で JVM のまま確かめると、ビルドの回数を減らせる

参考・出典

確認日はいずれも 2026年10月13日です。

  • Spring Boot Reference「Introducing GraalVM Native Images」:https://docs.spring.io/spring-boot/reference/packaging/native-image/introducing-graalvm-native-images.html
  • Spring Boot Reference「Advanced Native Images Topics」:https://docs.spring.io/spring-boot/reference/packaging/native-image/advanced-topics.html
  • Spring Boot How-to「Developing Your First GraalVM Native Application」:https://docs.spring.io/spring-boot/how-to/native-image/developing-your-first-application.html
  • Spring Boot How-to「Ahead-of-Time Processing」:https://docs.spring.io/spring-boot/how-to/aot.html
  • Spring Boot v4.1.1 ソース(gradle.properties・ドキュメントのサンプル):https://github.com/spring-projects/spring-boot/tree/v4.1.1
  • Spring Framework v7.0.9 ソース(org.springframework.aot.hint):https://github.com/spring-projects/spring-framework/tree/v7.0.9
  • GraalVM CE 25.0.2 リリース:https://github.com/graalvm/graalvm-ce-builds/releases/tag/jdk-25.0.2
  • GraalVM Reachability Metadata:https://github.com/oracle/graalvm-reachability-metadata

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Spring BootのGraalVMネイティブイメージ|作り方と制約」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?