Micronaut + GraalVM = <3
Iván López
(@ilopmar)
Iván López @ilopmar
Iván López (@ilopmar)
Iván López @ilopmar
- Universal Polyglot VM de Oracle
- Lenguajes de la JVM + Ruby, Python, JS, R
- Graal Compiler / JVMCI
- Truffle
- Substrate VM
GraalVM
Iván López @ilopmar
- Reflection (con configuración)
- Dynamic class loading (con configuración)
- Dynamic proxy (con configuración)
- Unsafe Memory Access (parcialmente)
- Class initializers (soportado)
- InvokeDynamic bytecode y method handlers (parcialmente)
- Lambda (soportado)
- Finalizers (no soportado)
- Threads (parcialmente)
Limitaciones
Iván López @ilopmar
- Framework para microservicios en la JVM
- Ultra-ligero & reactive (basado en Netty)
- Java, Groovy & Kotlin
- Ahead of Time compilation (AoT)
- Sin reflection ni runtime proxies
- Arranque muy rápido
- Consumo de memoria bajo
- Natively Cloud Native
- Micronaut Data
- Soporte para GraalVM (mejorado en Micronaut 2.0)
Micronaut
Iván López @ilopmar
$ mn create-app basic-app
--features=graalvm
Crear aplicación con soporte para GraalVM
Iván López @ilopmar
$ mn create-app basic-app
--features=graalvm
Crear aplicación con soporte para GraalVM
Micronaut 2.1 & Gradle
Iván López @ilopmar
$ ./gradlew nativeImage
Crear native image
$ ./gradlew dockerBuildNative
Iván López @ilopmar
- Composable native-image.properties
¿Cómo funciona?
Iván López @ilopmar
# inject/native-image.properties
Args = --allow-incomplete-classpath 
-H:EnableURLProtocols=http,https
# http/native-image.properties
Args = -H:IncludeResources=META-INF/http/mime.types
# http-netty/native-image.properties
Args = --initialize-at-run-time=
com.sun.jndi.dns.DnsClient,io.netty.handler.ssl.ConscryptAlpnSslEngine,io.netty.handler.ssl.Je
ttyNpnSslEngine,io.netty.handler.ssl.ReferenceCountedOpenSslEngine,io.netty.handler.ssl.JdkNpn
ApplicationProtocolNegotiator,io.netty.handler.ssl.ReferenceCountedOpenSslServerContext,io.net
ty.handler.ssl.ReferenceCountedOpenSslClientContext,io.netty.handler.ssl.util.BouncyCastleSelf
SignedCertGenerator,io.netty.handler.ssl.ReferenceCountedOpenSslContext,io.micronaut.buffer.ne
tty.NettyByteBufferFactory,io.netty.handler.ssl.JettyAlpnSslEngine$ClientEngine,io.netty.handl
er.ssl.JettyAlpnSslEngine$ServerEngine,io.netty.handler.codec.http2.Http2CodecUtil,io.netty.ha
ndler.codec.http2.CleartextHttp2ServerUpgradeHandler,io.netty.handler.codec.http2.Http2ServerU
pgradeCodec,io.micronaut.http.netty.channel.converters.EpollChannelOptionFactory,io.micronaut.
http.netty.channel.converters.KQueueChannelOptionFactory,io.micronaut.http.bind.binders.Contin
uationArgumentBinder$Companion,io.micronaut.http.bind.binders.ContinuationArgumentBinder
Micronaut incluye todo lo necesario (I)
Iván López @ilopmar
@AutomaticFeature
final class HibernateFeature implements Feature {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
// other drivers...
registerIfPresent(access, "oracle.jdbc.OracleDriver",
Oracle8iDialect.class,
Oracle9iDialect.class,
Oracle10gDialect.class,
Oracle12cDialect.class);
}
}
Micronaut incluye todo lo necesario (II)
Iván López @ilopmar
private void handleOracle(BeforeAnalysisAccess access) {
Class<?> oracleDriver = access.findClassByName(ORACLE_DRIVER);
if (oracleDriver != null) {
registerAllIfPresent(access, "oracle.jdbc.driver.T4CDriverExtension");
registerAllIfPresent(access, "oracle.jdbc.driver.T2CDriverExtension");
registerAllIfPresent(access, "oracle.net.ano.Ano");
registerAllIfPresent(access, "oracle.net.ano.AuthenticationService");
registerAllIfPresent(access, "oracle.net.ano.DataIntegrityService");
registerAllIfPresent(access, "oracle.net.ano.EncryptionService");
registerAllIfPresent(access, "oracle.net.ano.SupervisorService");
ResourcesRegistry resourcesRegistry = getResourceRegistry();
if (resourcesRegistry != null) {
resourcesRegistry.addResources("META-INF/services/java.sql.Driver");
resourcesRegistry.addResources("oracle/sql/converter_xcharset/lx20002.glb");
resourcesRegistry.addResources("oracle/sql/converter_xcharset/lx2001f.glb");
resourcesRegistry.addResources("oracle/sql/converter_xcharset/lx200b2.glb");
resourcesRegistry.addResourceBundles("oracle.net.jdbc.nl.mesg.NLSR");
resourcesRegistry.addResourceBundles("oracle.net.mesg.Message");
}
initializeAtBuildTime(access,
"oracle.net.jdbc.nl.mesg.NLSR_en",
"oracle.jdbc.driver.DynamicByteArray",
"oracle.sql.ConverterArchive",
"oracle.sql.converter.CharacterConverterJDBC",
"oracle.sql.converter.CharacterConverter1Byte"
);
initializeAtRuntime(access, "java.sql.DriverManager");
}
}
Micronaut incluye todo lo necesario (III)
Iván López @ilopmar
Micronaut incluye todo lo necesario (IV)
Iván López @ilopmar
Micronaut incluye todo lo necesario (V)
Iván López @ilopmar
- @Introspected
- @TypeHint
- @ReflectiveAccess
- GraalTypeElementVisitor
-reflection-config.json
-resource-config.json (* Micronaut 2.0)
Soporte en Micronaut
DEMO
Iván López @ilopmar
Demo
Iván López @ilopmar
11 vs 134 MB
¿Y la memoria?
Iván López @ilopmar
- Crear una imagen nativa tarda mucho
- Y necesita mucha RAM
- GraalVM cambia muy rápido (y a veces rompen cosas)...
- ...y nosotros también ;-)
- Usabamos Travis para Micronaut (ahora Github Actions), pero...
- ...Travis tiene límite para la RAM
- Necesitábamos otra opción.
Y esto… ¿Cómo se testea?
Iván López @ilopmar
- Jobs periódicos cada hora (2.2.x / 2.1.x)
- Sólo si nuevos commit en Micronaut o GraalVM
- Compila GraalVM desde el código fuente (JDK8 & JDK 11)
- Crea imágenes nativas de aplicaciones de prueba de Micronaut
- Ejecuta tests funcionales
- https://github.com/micronaut-graal-tests
- https://gitlab.com/micronaut-projects/micronaut-graal-tests
Tests usando Gitlab CI
Iván López @ilopmar
- Basic application: DI, serialización de POJO, tipos reactivos,
HTTP Client
- Cache
- Micronaut function
- Service discovery: Consul & Eureka
- Static resources & views: Handlebars, Thymeleaf, Freemarker y Velocity
- Endpoints de Management & Metrics
- Distributed tracing: Zipkin
- RabbitMQ: Fire-and-forget & RPC
Aplicaciones de prueba Micronaut-GraalVM
Iván López @ilopmar
- Security: JWT, Basic Auth, Cookie, Session
- Scheduled jobs
- Micronaut Data JDBC: H2, Postgresql, Oracle, MariaDB, MS SQL Server
- Micronaut Data JPA-Hibernate: H2, Postgresql, MariaDB
- Bean Introspection
- Servlet: Tomcat & Jetty
- Flyway
- AWS app & function
- gRPC
Aplicaciones de prueba Micronaut-GraalVM
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI
Iván López @ilopmar
Gitlab CI hace 20 meses
Iván López @ilopmar
x4
- JDK 8 & 11
- 2.2.x & 2.1.x
Gitlab CI hoy
Iván López @ilopmar
Runners propios en AWS
Iván López @ilopmar
Casos de uso
Iván López @ilopmar
- https://launch.micronaut.io (Google Cloud)
- Micronaut CLI: Linux, MacOS, Windows
- AWS Lambda + Custom runtime
Casos de uso
Iván López @ilopmar
GraalVM es una tecnología
nueva e interesante
Cuidado con las
limitaciones y casos de uso
Soporte out-of-the-box
en Micronaut
Mejoras en cada release Arranque más rápido &
menos consumo de
memoria
Desarrolladores
contentos y productivos
Resumen
¡Gracias!
@ilopmar
lopez.ivan@gmail.com
https://github.com/ilopmar
Iván López
https://bit.ly/jconf-peru-mn-graalvm
¿Preguntas?

JConf Perú 2020 - Micronaut + GraalVM = <3

  • 1.
    Micronaut + GraalVM= <3 Iván López (@ilopmar)
  • 2.
    Iván López @ilopmar IvánLópez (@ilopmar)
  • 4.
    Iván López @ilopmar -Universal Polyglot VM de Oracle - Lenguajes de la JVM + Ruby, Python, JS, R - Graal Compiler / JVMCI - Truffle - Substrate VM GraalVM
  • 5.
    Iván López @ilopmar -Reflection (con configuración) - Dynamic class loading (con configuración) - Dynamic proxy (con configuración) - Unsafe Memory Access (parcialmente) - Class initializers (soportado) - InvokeDynamic bytecode y method handlers (parcialmente) - Lambda (soportado) - Finalizers (no soportado) - Threads (parcialmente) Limitaciones
  • 7.
    Iván López @ilopmar -Framework para microservicios en la JVM - Ultra-ligero & reactive (basado en Netty) - Java, Groovy & Kotlin - Ahead of Time compilation (AoT) - Sin reflection ni runtime proxies - Arranque muy rápido - Consumo de memoria bajo - Natively Cloud Native - Micronaut Data - Soporte para GraalVM (mejorado en Micronaut 2.0) Micronaut
  • 8.
    Iván López @ilopmar $mn create-app basic-app --features=graalvm Crear aplicación con soporte para GraalVM
  • 9.
    Iván López @ilopmar $mn create-app basic-app --features=graalvm Crear aplicación con soporte para GraalVM Micronaut 2.1 & Gradle
  • 10.
    Iván López @ilopmar $./gradlew nativeImage Crear native image $ ./gradlew dockerBuildNative
  • 11.
    Iván López @ilopmar -Composable native-image.properties ¿Cómo funciona?
  • 12.
    Iván López @ilopmar #inject/native-image.properties Args = --allow-incomplete-classpath -H:EnableURLProtocols=http,https # http/native-image.properties Args = -H:IncludeResources=META-INF/http/mime.types # http-netty/native-image.properties Args = --initialize-at-run-time= com.sun.jndi.dns.DnsClient,io.netty.handler.ssl.ConscryptAlpnSslEngine,io.netty.handler.ssl.Je ttyNpnSslEngine,io.netty.handler.ssl.ReferenceCountedOpenSslEngine,io.netty.handler.ssl.JdkNpn ApplicationProtocolNegotiator,io.netty.handler.ssl.ReferenceCountedOpenSslServerContext,io.net ty.handler.ssl.ReferenceCountedOpenSslClientContext,io.netty.handler.ssl.util.BouncyCastleSelf SignedCertGenerator,io.netty.handler.ssl.ReferenceCountedOpenSslContext,io.micronaut.buffer.ne tty.NettyByteBufferFactory,io.netty.handler.ssl.JettyAlpnSslEngine$ClientEngine,io.netty.handl er.ssl.JettyAlpnSslEngine$ServerEngine,io.netty.handler.codec.http2.Http2CodecUtil,io.netty.ha ndler.codec.http2.CleartextHttp2ServerUpgradeHandler,io.netty.handler.codec.http2.Http2ServerU pgradeCodec,io.micronaut.http.netty.channel.converters.EpollChannelOptionFactory,io.micronaut. http.netty.channel.converters.KQueueChannelOptionFactory,io.micronaut.http.bind.binders.Contin uationArgumentBinder$Companion,io.micronaut.http.bind.binders.ContinuationArgumentBinder Micronaut incluye todo lo necesario (I)
  • 13.
    Iván López @ilopmar @AutomaticFeature finalclass HibernateFeature implements Feature { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { // other drivers... registerIfPresent(access, "oracle.jdbc.OracleDriver", Oracle8iDialect.class, Oracle9iDialect.class, Oracle10gDialect.class, Oracle12cDialect.class); } } Micronaut incluye todo lo necesario (II)
  • 14.
    Iván López @ilopmar privatevoid handleOracle(BeforeAnalysisAccess access) { Class<?> oracleDriver = access.findClassByName(ORACLE_DRIVER); if (oracleDriver != null) { registerAllIfPresent(access, "oracle.jdbc.driver.T4CDriverExtension"); registerAllIfPresent(access, "oracle.jdbc.driver.T2CDriverExtension"); registerAllIfPresent(access, "oracle.net.ano.Ano"); registerAllIfPresent(access, "oracle.net.ano.AuthenticationService"); registerAllIfPresent(access, "oracle.net.ano.DataIntegrityService"); registerAllIfPresent(access, "oracle.net.ano.EncryptionService"); registerAllIfPresent(access, "oracle.net.ano.SupervisorService"); ResourcesRegistry resourcesRegistry = getResourceRegistry(); if (resourcesRegistry != null) { resourcesRegistry.addResources("META-INF/services/java.sql.Driver"); resourcesRegistry.addResources("oracle/sql/converter_xcharset/lx20002.glb"); resourcesRegistry.addResources("oracle/sql/converter_xcharset/lx2001f.glb"); resourcesRegistry.addResources("oracle/sql/converter_xcharset/lx200b2.glb"); resourcesRegistry.addResourceBundles("oracle.net.jdbc.nl.mesg.NLSR"); resourcesRegistry.addResourceBundles("oracle.net.mesg.Message"); } initializeAtBuildTime(access, "oracle.net.jdbc.nl.mesg.NLSR_en", "oracle.jdbc.driver.DynamicByteArray", "oracle.sql.ConverterArchive", "oracle.sql.converter.CharacterConverterJDBC", "oracle.sql.converter.CharacterConverter1Byte" ); initializeAtRuntime(access, "java.sql.DriverManager"); } } Micronaut incluye todo lo necesario (III)
  • 15.
    Iván López @ilopmar Micronautincluye todo lo necesario (IV)
  • 16.
    Iván López @ilopmar Micronautincluye todo lo necesario (V)
  • 17.
    Iván López @ilopmar -@Introspected - @TypeHint - @ReflectiveAccess - GraalTypeElementVisitor -reflection-config.json -resource-config.json (* Micronaut 2.0) Soporte en Micronaut
  • 18.
  • 19.
  • 20.
    Iván López @ilopmar 11vs 134 MB ¿Y la memoria?
  • 21.
    Iván López @ilopmar -Crear una imagen nativa tarda mucho - Y necesita mucha RAM - GraalVM cambia muy rápido (y a veces rompen cosas)... - ...y nosotros también ;-) - Usabamos Travis para Micronaut (ahora Github Actions), pero... - ...Travis tiene límite para la RAM - Necesitábamos otra opción. Y esto… ¿Cómo se testea?
  • 23.
    Iván López @ilopmar -Jobs periódicos cada hora (2.2.x / 2.1.x) - Sólo si nuevos commit en Micronaut o GraalVM - Compila GraalVM desde el código fuente (JDK8 & JDK 11) - Crea imágenes nativas de aplicaciones de prueba de Micronaut - Ejecuta tests funcionales - https://github.com/micronaut-graal-tests - https://gitlab.com/micronaut-projects/micronaut-graal-tests Tests usando Gitlab CI
  • 24.
    Iván López @ilopmar -Basic application: DI, serialización de POJO, tipos reactivos, HTTP Client - Cache - Micronaut function - Service discovery: Consul & Eureka - Static resources & views: Handlebars, Thymeleaf, Freemarker y Velocity - Endpoints de Management & Metrics - Distributed tracing: Zipkin - RabbitMQ: Fire-and-forget & RPC Aplicaciones de prueba Micronaut-GraalVM
  • 25.
    Iván López @ilopmar -Security: JWT, Basic Auth, Cookie, Session - Scheduled jobs - Micronaut Data JDBC: H2, Postgresql, Oracle, MariaDB, MS SQL Server - Micronaut Data JPA-Hibernate: H2, Postgresql, MariaDB - Bean Introspection - Servlet: Tomcat & Jetty - Flyway - AWS app & function - gRPC Aplicaciones de prueba Micronaut-GraalVM
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
    Iván López @ilopmar x4 -JDK 8 & 11 - 2.2.x & 2.1.x Gitlab CI hoy
  • 36.
  • 37.
  • 38.
    Iván López @ilopmar -https://launch.micronaut.io (Google Cloud) - Micronaut CLI: Linux, MacOS, Windows - AWS Lambda + Custom runtime Casos de uso
  • 39.
    Iván López @ilopmar GraalVMes una tecnología nueva e interesante Cuidado con las limitaciones y casos de uso Soporte out-of-the-box en Micronaut Mejoras en cada release Arranque más rápido & menos consumo de memoria Desarrolladores contentos y productivos Resumen
  • 40.