Tras estos posts sobre GraalVM en los que presentábamos GraalVM y contábamos cómo instalarlo y generar una aplicación nativa GraalVM llega el momento de ver cómo generar un ejecutable nativo GraalVM de nuestra aplicación Spring Boot.
Para esto usaremos el proyecto spring-native-graalvm que aún está en estado experimental pero ya nos permite de una forma muy sencilla generar aplicaciones nativas GraalVM de aplicaciones Spring Boot. Y el Por fin!!! es porque aunque en Spring han sido rápidos, hasta finales de 2020 no hemos tenido esta posibilidad y los pasos eran bastante más complejos, y por otro es fundamental que la tecnología Java más usada en la actualidad (Spring) tuviera soporte para crear aplicaciones nativas GraalVM más cuando otras tecnologías como Micronauy o Quarkus ya la tenían.
Empezaremos por descargarnos el proyecto de ejemplo del que partimos que no es más que un servicio REST Greeting,
para esto:
git clone https://github.com/spring-guides/gs-rest-service
cd gs-rest-service/complete
Tras esto debemos actualizar el pom.xml para usar al menos Spring Boot 2.4.1 que es la primera versión de Spring que tiene soporte para generar nativos GraalVM:
Antes de empezar con el proceso ejecutaremos la aplicación original, para eso ejecutamos mvn spring-boot:run
En nuestro caso podemos ver cómo la aplicación tarda unos 2 segundos en arrancar (dependiendo de la carga y demás)
En este post nos ocuparemos de usar el plugin de Maven con soporte para Buildpacks para generar un contenedor ligero que contendrá el ejecutable nativo GraalVM.
Para esto editaremos el pom.xml y añadiremos este plugin:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_BOOT_NATIVE_IMAGE>true</BP_BOOT_NATIVE_IMAGE>
<BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS>
-Dspring.native.remove-yaml-support=true
-Dspring.spel.ignore=true
</BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS>
</env>
</image>
</configuration>
</plugin>
Estoy configurando este plugins con unos flags que reducen el footprint, además e usar el builder:tiny de los Paketo BuildPacks (en lugar del builder:base)
Luego añadiremos estos 2 repositorios:
<repositories>
<repository>
<id>spring-milestone</id>
<name>Spring milestone</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
y
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<name>Spring milestone</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
Antes de lanzar la generación de la imagen que es un proceso costoso en recursos puede ser necesario incrementar la memoria asignada a Docker, en mi caso he pasado a 3 Gbs en lugar d ellos 3 Gbs por defecto.
Ahora ya estoy en disposición de generar la imagen con el comando:
mvn spring-boot:build-image
(si estoy ejecutando en Windows tendré que ejecutarlo desde una Shell tipo la de MINGW que trae el cliente de github):
El proceso de generación de la imagen es costoso y lento (en mi caso 14 minutos):
Una vez generada podré ejecutar el contenedor Docker de la aplicación Spring Boot:
docker run -p 8080:8080 docker.io/library/rest-service:0.0.1-SNAPSHOT
donde puedo ver que ahora el tiempo de arranque es prácticamente instantáneo (menos de 100 ms)








Replica a Ernesto Cancelar la respuesta