warning
この記事は2年以上前に更新されたものです。情報が古くなっている可能性があります。

🚨🚨 Paketo Buildpackで正式にGraalVM buildpackが同梱されたため、本記事の内容はDEPRECATEDになりました。正式版はこちらの記事を確認してください。 🚨🚨️

Spring BootアプリをGraalVMでnative image化するプロジェクトSpring GraalVM Native Featureの開発が進んでいますが、
java-native-image Buildpackを使えば、
Spring BootのアプリをGraalVM+spring-graalvm-nativeを使ってnative image化できます。
GraalVMもspring-graalvm-nativeもインストール不要で、普通のソースコードからビルド可能です。

Paketo Buildpacks標準のjava buildpackがJREとしてbellsoft-liberica buildpackを内包しているのに対して、
java-native-image buildpackは、graalvm buildpackを内包しています。

Paketo Buildpacksのgcr.io/paketo-buildpacks/builder:base builderにはjava-native-image buildpackは含まれないので、
java-native-image buildpackを含むbuilderを自分で作成します。

次のようなbuilder.tomlを作成します。

[[buildpacks]]
id = "paketo-buildpacks/java-native-image"
version = "2.5.0"
image = "gcr.io/paketo-buildpacks/java-native-image:2.5.0"

[[order]]
group = [
    { id = "paketo-buildpacks/java-native-image", version = "2.5.0" }
]

[stack]
id = "io.buildpacks.stacks.bionic"
run-image = "gcr.io/paketo-buildpacks/run:base-cnb"
build-image = "gcr.io/paketo-buildpacks/build:base-cnb"

builderを作成する方法は

pack create-builder <builder image名> -c builder.toml

です。making/java-native-image-cnb-builderにpublishしてあります。

Note: 本記事で扱うjava-native-image buildpackのバージョンは2.5.0であり、
含まれるバージョンは

  • GraalVM 20.1.0
  • Spring GraalVM Native Feature 0.7.1

です。

Stackにio.paketo.stacks.tinyはまだ使えません。GraalVM 20.2.0が必要で、おそらく次のバージョンで使えるようになります (参考コミット))。

ビルドできるアプリにも制限があります。

https://github.com/spring-projects-experimental/spring-graalvm-native/tree/0.7.1/spring-graalvm-native-samples にあるアプリの多くはビルドできると思います。

このbuilderを使って実際にSpring Bootアプリのnative imageを作成します。

まずはソースコードを用意します。

curl https://start.spring.io/starter.tgz \
  -s \
  -d javaVersion=11 \
  -d artifactId=hello \
  -d baseDir=hello \
  -d dependencies=webflux,actuator \
  -d packageName=com.example \
  -d applicationName=HelloApplication | tar -xzvf -
sed -i.bak 's/@SpringBootApplication/@SpringBootApplication(proxyBeanMethods = false)/' hello/src/main/java/com/example/HelloApplication.java
rm -f hello/src/main/java/com/example/HelloApplication.java.bak

cd hello
./mvnw clean package -Dmaven.test.skip=true

イメージを作成するには

があります。

pack CLIを使う方法

pack 0.12.0で動作確認しています。

pack build hello \
  --builder making/java-native-image-cnb-builder \
  --path target/hello*.jar \
  -e BP_BOOT_NATIVE_IMAGE=1

次のようなログが出力されます。

latest: Pulling from making/java-native-image-cnb-builder
Digest: sha256:6b68612c193ffff147cf70dd46581fa2740c8c7fa817ebe077e05d13eb1f3947
Status: Image is up to date for making/java-native-image-cnb-builder:latest
base-cnb: Pulling from paketo-buildpacks/run
Digest: sha256:1303a41dfeebb0450640655ad464c66af5c2a500e20ad86d5687f00c4805d971
Status: Image is up to date for gcr.io/paketo-buildpacks/run:base-cnb
0.8.0: Pulling from buildpacksio/lifecycle
Digest: sha256:48dfb79e342fdeb68a1bf310b33b349269b2919cb5029e0b7184b84e82fc0bb3
Status: Image is up to date for buildpacksio/lifecycle:0.8.0
===> DETECTING
[detector] 3 of 9 buildpacks participating
[detector] paketo-buildpacks/graalvm        2.1.0
[detector] paketo-buildpacks/executable-jar 2.1.1
[detector] paketo-buildpacks/spring-boot    2.5.0
===> ANALYZING
[analyzer] Previous image with name "index.docker.io/library/hello:latest" not found
===> RESTORING
===> BUILDING
[builder] 
[builder] Paketo GraalVM Buildpack 2.1.0
[builder]   https://github.com/paketo-buildpacks/graalvm
[builder]   Build Configuration:
[builder]     $BP_JVM_VERSION              11.*            the Java version
[builder]   Launch Configuration:
[builder]     $BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation
[builder]     $BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation
[builder]     $BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation
[builder]     $JAVA_OPTS                                   the flags that influence JVM memory configuration at launch
[builder]   GraalVM JDK 11.0.7: Contributing to layer
[builder]     Downloading from https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.1.0/graalvm-ce-java11-linux-amd64-20.1.0.tar.gz
[builder]     Verifying checksum
[builder]     Expanding to /layers/paketo-buildpacks_graalvm/jdk
[builder]     Adding 127 container CA certificates to JVM truststore
[builder]   GraalVM Native Image Substrate VM 11.0.7
[builder]     Downloading from https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.1.0/native-image-installable-svm-java11-linux-amd64-20.1.0.jar
[builder]     Verifying checksum
[builder]     Installing substrate VM
[builder] Processing Component archive: /tmp/dfee7b7872bc4448ce6df6732adcd01e2758de1133233dabf921d8e98f5f79c9/native-image-installable-svm-java11-linux-amd64-20.1.0.jar
[builder] Installing new component: Native Image (org.graalvm.native-image, version 20.1.0)
[builder]     Writing env.build/JAVA_HOME.override
[builder]     Writing env.build/JDK_HOME.override
[builder] 
[builder] Paketo Executable JAR Buildpack 2.1.1
[builder]   https://github.com/paketo-buildpacks/executable-jar
[builder]   Launch Configuration:
[builder]     $JAVA_OPTS  the flags passed to the JVM process at launch
[builder] 
[builder] Paketo Spring Boot Buildpack 2.5.0
[builder]   https://github.com/paketo-buildpacks/spring-boot
[builder]   Build Configuration:
[builder]     $BP_BOOT_NATIVE_IMAGE                  1  the build to create a native image (requires GraalVM)
[builder]     $BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS     the arguments to pass to the native-image command
[builder]   Launch Configuration:
[builder]     $BPL_SPRING_CLOUD_BINDINGS_ENABLED        whether to auto-configure Spring Boot environment properties from bindings
[builder]   Native Image: Contributing to layer
[builder]   Spring GraalVM Native Feature 0.7.1
[builder]     Downloading from https://repo.spring.io/milestone/org/springframework/experimental/spring-graalvm-native/0.7.1/spring-graalvm-native-0.7.1.jar
[builder]     Verifying checksum
[builder]     Executing native-image -H:Name=/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication -cp /workspace:/workspace/BOOT-INF/classes:/workspace/BOOT-INF/lib/spring-boot-starter-actuator-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-starter-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-context-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-aop-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-expression-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-autoconfigure-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-starter-logging-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/logback-classic-1.2.3.jar:/workspace/BOOT-INF/lib/logback-core-1.2.3.jar:/workspace/BOOT-INF/lib/log4j-to-slf4j-2.13.3.jar:/workspace/BOOT-INF/lib/log4j-api-2.13.3.jar:/workspace/BOOT-INF/lib/jul-to-slf4j-1.7.30.jar:/workspace/BOOT-INF/lib/jakarta.annotation-api-1.3.5.jar:/workspace/BOOT-INF/lib/snakeyaml-1.26.jar:/workspace/BOOT-INF/lib/spring-boot-actuator-autoconfigure-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-actuator-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/jackson-databind-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-annotations-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-core-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-datatype-jsr310-2.11.1.jar:/workspace/BOOT-INF/lib/micrometer-core-1.5.3.jar:/workspace/BOOT-INF/lib/HdrHistogram-2.1.12.jar:/workspace/BOOT-INF/lib/LatencyUtils-2.0.3.jar:/workspace/BOOT-INF/lib/spring-boot-starter-webflux-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-starter-json-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/jackson-datatype-jdk8-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-module-parameter-names-2.11.1.jar:/workspace/BOOT-INF/lib/spring-boot-starter-reactor-netty-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/reactor-netty-0.9.10.RELEASE.jar:/workspace/BOOT-INF/lib/netty-codec-http-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-common-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-buffer-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-transport-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-codec-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-codec-http2-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-handler-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-resolver-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-handler-proxy-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-codec-socks-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-transport-native-epoll-4.1.51.Final-linux-x86_64.jar:/workspace/BOOT-INF/lib/netty-transport-native-unix-common-4.1.51.Final.jar:/workspace/BOOT-INF/lib/spring-web-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-beans-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-webflux-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/nio-multipart-parser-1.1.0.jar:/workspace/BOOT-INF/lib/slf4j-api-1.7.30.jar:/workspace/BOOT-INF/lib/nio-stream-storage-1.1.3.jar:/workspace/BOOT-INF/lib/spring-core-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-jcl-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/reactor-core-3.3.8.RELEASE.jar:/workspace/BOOT-INF/lib/reactive-streams-1.0.3.jar:/tmp/af5792294734e26620bcd13868a2e6f53c20008c0232dac42669f826efd2d3f2/spring-graalvm-native-0.7.1.jar com.example.HelloApplication
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]    classlist:   8,663.73 ms,  0.96 GB
[builder]  ____             _               _____          _                  
[builder] / ___| _ __  _ __(_)_ __   __ _  |  ___|__  __ _| |_ _   _ _ __ ___ 
[builder] \___ \| '_ \| '__| | '_ \ / _` | | |_ / _ \/ _` | __| | | | '__/ _ \
[builder]  ___) | |_) | |  | | | | | (_| | |  _|  __/ (_| | |_| |_| | | |  __/
[builder] |____/| .__/|_|  |_|_| |_|\__, | |_|  \___|\__,_|\__|\__,_|_|  \___|
[builder]       |_|                 |___/                                     
[builder] 
[builder] Feature operating in FEATURE mode
[builder] Removing unused configurations
[builder] Use -Dspring.native.verbose=true on native-image call to see more detailed information from the feature
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]        (cap):     591.55 ms,  0.96 GB
[builder] Found #6 types in static reflection list to register
... 略 ...
[builder] WARNING: Could not register reflection metadata for org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration. Reason: java.lang.NoClassDefFoundError: org/springframework/web/servlet/handler/MatchableHandlerMapping.
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]     (clinit):   2,300.61 ms,  6.80 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]   (typeflow):  51,564.07 ms,  6.80 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]    (objects):  44,682.72 ms,  6.80 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]   (features):   8,352.54 ms,  6.80 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]     analysis: 112,177.54 ms,  6.80 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]     universe:   2,355.91 ms,  6.80 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]      (parse):   6,443.61 ms,  6.81 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]     (inline):   5,094.46 ms,  6.75 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]    (compile):  38,105.19 ms,  6.33 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]      compile:  53,628.59 ms,  6.33 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]        image:   8,053.78 ms,  6.22 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]        write:   1,096.84 ms,  6.22 GB
[builder] [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:60]      [total]: 189,406.41 ms,  6.22 GB
[builder]   Removing bytecode
[builder]   Image labels:
[builder]     org.opencontainers.image.title
[builder]     org.opencontainers.image.version
[builder]     org.springframework.boot.spring-configuration-metadata.json
[builder]     org.springframework.boot.version
[builder]   Process types:
[builder]     native-image: /workspace/com.example.HelloApplication (direct)
[builder]     task:         /workspace/com.example.HelloApplication (direct)
[builder]     web:          /workspace/com.example.HelloApplication (direct)
===> EXPORTING
[exporter] Adding layer 'launcher'
[exporter] Adding 1/1 app layer(s)
[exporter] Adding layer 'config'
[exporter] *** Images (e5d15c3ca887):
[exporter]       index.docker.io/library/hello:latest
[exporter] Adding cache layer 'paketo-buildpacks/graalvm:jdk'
[exporter] Adding cache layer 'paketo-buildpacks/spring-boot:native-image'
Successfully built image hello

Spring Boot Maven/Gradle Pluginを使う方法

Maven Pluginを使う例を紹介します。pom.xmlに以下の箇所を追加します。

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- from -->
                <configuration>
                    <image>
                        <builder>making/java-native-image-cnb-builder</builder>
                        <env>
                            <BP_BOOT_NATIVE_IMAGE>1</BP_BOOT_NATIVE_IMAGE>
                        </env>
                    </image>
                </configuration>
                <!-- to -->
            </plugin>
        </plugins>
    </build>
./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=hello

次のようなログが出力されます。

[INFO] --- spring-boot-maven-plugin:2.3.2.RELEASE:build-image (default-cli) @ hello ---
[INFO] Building image 'docker.io/library/hello:latest'
[INFO] 
[INFO]  > Pulling builder image 'docker.io/making/java-native-image-cnb-builder:latest' 100%
[INFO]  > Pulled builder image 'making/java-native-image-cnb-builder@sha256:6b68612c193ffff147cf70dd46581fa2740c8c7fa817ebe077e05d13eb1f3947'
[INFO]  > Pulling run image 'gcr.io/paketo-buildpacks/run:base-cnb' 100%
[INFO]  > Pulled run image 'gcr.io/paketo-buildpacks/run@sha256:1303a41dfeebb0450640655ad464c66af5c2a500e20ad86d5687f00c4805d971'
[INFO]  > Executing lifecycle version v0.8.0
[INFO]  > Using build cache volume 'pack-cache-ae2811f8f959.build'
[INFO] 
[INFO]  > Running creator
[INFO]     [creator]     ===> DETECTING
[INFO]     [creator]     3 of 9 buildpacks participating
[INFO]     [creator]     paketo-buildpacks/graalvm        2.1.0
[INFO]     [creator]     paketo-buildpacks/executable-jar 2.1.1
[INFO]     [creator]     paketo-buildpacks/spring-boot    2.5.0
[INFO]     [creator]     ===> ANALYZING
[INFO]     [creator]     Restoring metadata for "paketo-buildpacks/graalvm:jdk" from cache
[INFO]     [creator]     Restoring metadata for "paketo-buildpacks/spring-boot:native-image" from cache
[INFO]     [creator]     ===> RESTORING
[INFO]     [creator]     Restoring data for "paketo-buildpacks/graalvm:jdk" from cache
[INFO]     [creator]     Restoring data for "paketo-buildpacks/spring-boot:native-image" from cache
[INFO]     [creator]     ===> BUILDING
[INFO]     [creator]     
[INFO]     [creator]     Paketo GraalVM Buildpack 2.1.0
[INFO]     [creator]       https://github.com/paketo-buildpacks/graalvm
[INFO]     [creator]       Build Configuration:
[INFO]     [creator]         $BP_JVM_VERSION              11.*            the Java version
[INFO]     [creator]       Launch Configuration:
[INFO]     [creator]         $BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation
[INFO]     [creator]         $BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation
[INFO]     [creator]         $BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation
[INFO]     [creator]         $JAVA_OPTS                                   the flags that influence JVM memory configuration at launch
[INFO]     [creator]       GraalVM JDK 11.0.7: Reusing cached layer
[INFO]     [creator]     
[INFO]     [creator]     Paketo Executable JAR Buildpack 2.1.1
[INFO]     [creator]       https://github.com/paketo-buildpacks/executable-jar
[INFO]     [creator]       Launch Configuration:
[INFO]     [creator]         $JAVA_OPTS  the flags passed to the JVM process at launch
[INFO]     [creator]     
[INFO]     [creator]     Paketo Spring Boot Buildpack 2.5.0
[INFO]     [creator]       https://github.com/paketo-buildpacks/spring-boot
[INFO]     [creator]       Build Configuration:
[INFO]     [creator]         $BP_BOOT_NATIVE_IMAGE                  1  the build to create a native image (requires GraalVM)
[INFO]     [creator]         $BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS     the arguments to pass to the native-image command
[INFO]     [creator]       Launch Configuration:
[INFO]     [creator]         $BPL_SPRING_CLOUD_BINDINGS_ENABLED        whether to auto-configure Spring Boot environment properties from bindings
[INFO]     [creator]       Native Image: Contributing to layer
[INFO]     [creator]       Spring GraalVM Native Feature 0.7.1
[INFO]     [creator]         Downloading from https://repo.spring.io/milestone/org/springframework/experimental/spring-graalvm-native/0.7.1/spring-graalvm-native-0.7.1.jar
[INFO]     [creator]         Verifying checksum
[INFO]     [creator]         Executing native-image -H:Name=/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication -cp /workspace:/workspace/BOOT-INF/classes:/workspace/BOOT-INF/lib/spring-boot-starter-actuator-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-starter-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-context-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-aop-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-expression-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-autoconfigure-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-starter-logging-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/logback-classic-1.2.3.jar:/workspace/BOOT-INF/lib/logback-core-1.2.3.jar:/workspace/BOOT-INF/lib/log4j-to-slf4j-2.13.3.jar:/workspace/BOOT-INF/lib/log4j-api-2.13.3.jar:/workspace/BOOT-INF/lib/jul-to-slf4j-1.7.30.jar:/workspace/BOOT-INF/lib/jakarta.annotation-api-1.3.5.jar:/workspace/BOOT-INF/lib/snakeyaml-1.26.jar:/workspace/BOOT-INF/lib/spring-boot-actuator-autoconfigure-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-actuator-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/jackson-databind-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-annotations-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-core-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-datatype-jsr310-2.11.1.jar:/workspace/BOOT-INF/lib/micrometer-core-1.5.3.jar:/workspace/BOOT-INF/lib/HdrHistogram-2.1.12.jar:/workspace/BOOT-INF/lib/LatencyUtils-2.0.3.jar:/workspace/BOOT-INF/lib/spring-boot-starter-webflux-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/spring-boot-starter-json-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/jackson-datatype-jdk8-2.11.1.jar:/workspace/BOOT-INF/lib/jackson-module-parameter-names-2.11.1.jar:/workspace/BOOT-INF/lib/spring-boot-starter-reactor-netty-2.3.2.RELEASE.jar:/workspace/BOOT-INF/lib/reactor-netty-0.9.10.RELEASE.jar:/workspace/BOOT-INF/lib/netty-codec-http-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-common-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-buffer-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-transport-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-codec-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-codec-http2-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-handler-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-resolver-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-handler-proxy-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-codec-socks-4.1.51.Final.jar:/workspace/BOOT-INF/lib/netty-transport-native-epoll-4.1.51.Final-linux-x86_64.jar:/workspace/BOOT-INF/lib/netty-transport-native-unix-common-4.1.51.Final.jar:/workspace/BOOT-INF/lib/spring-web-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-beans-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-webflux-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/nio-multipart-parser-1.1.0.jar:/workspace/BOOT-INF/lib/slf4j-api-1.7.30.jar:/workspace/BOOT-INF/lib/nio-stream-storage-1.1.3.jar:/workspace/BOOT-INF/lib/spring-core-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/spring-jcl-5.2.8.RELEASE.jar:/workspace/BOOT-INF/lib/reactor-core-3.3.8.RELEASE.jar:/workspace/BOOT-INF/lib/reactive-streams-1.0.3.jar:/tmp/af5792294734e26620bcd13868a2e6f53c20008c0232dac42669f826efd2d3f2/spring-graalvm-native-0.7.1.jar com.example.HelloApplication
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]    classlist:  14,470.34 ms,  0.94 GB
[INFO]     [creator]      ____             _               _____          _                  
[INFO]     [creator]     / ___| _ __  _ __(_)_ __   __ _  |  ___|__  __ _| |_ _   _ _ __ ___ 
[INFO]     [creator]     \___ \| '_ \| '__| | '_ \ / _` | | |_ / _ \/ _` | __| | | | '__/ _ \
[INFO]     [creator]      ___) | |_) | |  | | | | | (_| | |  _|  __/ (_| | |_| |_| | | |  __/
[INFO]     [creator]     |____/| .__/|_|  |_|_| |_|\__, | |_|  \___|\__,_|\__|\__,_|_|  \___|
[INFO]     [creator]           |_|                 |___/                                     
[INFO]     [creator]     
[INFO]     [creator]     Feature operating in FEATURE mode
[INFO]     [creator]     Removing unused configurations
[INFO]     [creator]     Use -Dspring.native.verbose=true on native-image call to see more detailed information from the feature
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]        (cap):   1,032.42 ms,  0.94 GB
... 略 ...
[INFO]     [creator]     WARNING: Could not register reflection metadata for org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration. Reason: java.lang.NoClassDefFoundError: org/glassfish/jersey/server/ResourceConfig.
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]     (clinit):   1,918.19 ms,  6.40 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]   (typeflow):  93,152.84 ms,  6.40 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]    (objects):  67,539.00 ms,  6.40 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]   (features):   9,954.26 ms,  6.40 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]     analysis: 178,714.20 ms,  6.40 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]     universe:   2,655.73 ms,  6.40 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]      (parse):   5,248.44 ms,  6.14 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]     (inline):   4,960.91 ms,  6.27 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]    (compile):  42,658.53 ms,  5.99 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]      compile:  57,244.82 ms,  4.89 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]        image:   8,385.57 ms,  5.84 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]        write:   1,140.12 ms,  5.84 GB
[INFO]     [creator]     [/layers/paketo-buildpacks_spring-boot/native-image/com.example.HelloApplication:116]      [total]: 267,540.20 ms,  5.84 GB
[INFO]     [creator]       Removing bytecode
[INFO]     [creator]       Image labels:
[INFO]     [creator]         org.opencontainers.image.title
[INFO]     [creator]         org.opencontainers.image.version
[INFO]     [creator]         org.springframework.boot.spring-configuration-metadata.json
[INFO]     [creator]         org.springframework.boot.version
[INFO]     [creator]       Process types:
[INFO]     [creator]         native-image: /workspace/com.example.HelloApplication (direct)
[INFO]     [creator]         task:         /workspace/com.example.HelloApplication (direct)
[INFO]     [creator]         web:          /workspace/com.example.HelloApplication (direct)
[INFO]     [creator]     ===> EXPORTING
[INFO]     [creator]     Reusing layer 'launcher'
[INFO]     [creator]     Adding 1/1 app layer(s)
[INFO]     [creator]     Adding layer 'config'
[INFO]     [creator]     *** Images (79d72ef0f368):
[INFO]     [creator]           docker.io/library/hello:latest
[INFO]     [creator]     Adding cache layer 'paketo-buildpacks/graalvm:jdk'
[INFO]     [creator]     Adding cache layer 'paketo-buildpacks/spring-boot:native-image'
[INFO] 
[INFO] Successfully built image 'docker.io/library/hello:latest'
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  04:53 min
[INFO] Finished at: 2020-08-10T16:11:56+09:00
[INFO] ------------------------------------------------------------------------

ビルドしたイメージを実行します。

docker run --rm \
  -p 8080:8080 \
  -e MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE=info,health,env \
  hello
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                        

2020-08-10 07:09:41.512  INFO 1 --- [           main] com.example.HelloApplication             : Starting HelloApplication on 58021a13eb5a with PID 1 (/workspace/com.example.HelloApplication started by cnb in /workspace)
2020-08-10 07:09:41.513  INFO 1 --- [           main] com.example.HelloApplication             : No active profile set, falling back to default profiles: default
2020-08-10 07:09:41.610  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 3 endpoint(s) beneath base path '/actuator'
2020-08-10 07:09:41.618  WARN 1 --- [           main] i.m.c.i.binder.jvm.JvmGcMetrics          : GC notifications will not be available because MemoryPoolMXBeans are not provided by the JVM
2020-08-10 07:09:41.631  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2020-08-10 07:09:41.633  INFO 1 --- [           main] com.example.HelloApplication             : Started HelloApplication in 0.148 seconds (JVM running for 0.159)

非常に高速に起動します。

$ curl -s http://localhost:8080/actuator/env | jq '.propertySources[2].properties["java.vm.name"]'
{
  "value": "Substrate VM"
}

Substrate VMで動いていることがわかります。


非常に簡単にnative imageのdocker imageを作成できました。
今後さらに改善されていくと思うので期待。

Found a mistake? Update the entry.
Share this article: