🚨🚨 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-imagebuildpackのバージョンは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を作成できました。
今後さらに改善されていくと思うので期待。