package de.jotschi.examples; import java.io.File; import io.vertx.core.Vertx; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import io.vertx.core.logging.SLF4JLogDelegateFactory; import io.vertx.ext.web.Router; public class Runner { public static void main(String[] args) { // Use logback for logging File logbackFile = new File("config", "logback.xml"); System.setProperty("logback.configurationFile", logbackFile.getAbsolutePath()); System.setProperty(LoggerFactory.LOGGER_DELEGATE_FACTORY_CLASS_NAME, SLF4JLogDelegateFactory.class.getName()); Logger log = LoggerFactory.getLogger(Runner.class); // Setup the http server log.info("Starting server for: http://localhost:8080/hello"); Vertx vertx = Vertx.vertx(); Router router = Router.router(vertx); router.route("/hello").handler(rc -> { log.info("Got hello request"); rc.response().end("World"); }); vertx.createHttpServer() .requestHandler(router::accept) .listen(8080); } }
GraalVM Work in progress Next we need to apply some patches / workarounds. Keep in mind that native image generation is a fairly new topic and the these workarounds will hopefully no longer be required once the Substrate VM and Netty have better support for each other. |
io.vertx.core.net.impl.transport.Transport
class in order to prevent the loading of EPoll and KQueue native support. Otherwise Substrate VM will try to load these classes and fail.public class Transport { … /** * The native transport, it may be {@code null} or failed. */ public static Transport nativeTransport() { // Patched: I remove the native transport discovery. // The imports would be picked up by substrate // and cause further issues. return null; } … }
io.netty.handler.ssl.ReferenceCountedOpenSslEngine
class in order to prevent Substrate VM from digging deeper into the SSL code of Netty.reflectconfigs/netty.json
.[ { "name" : "io.netty.channel.socket.nio.NioSocketChannel", "methods" : [ { "name" : "", "parameterTypes" : [] } ] }, { "name" : "io.netty.channel.socket.nio.NioServerSocketChannel", "methods" : [ { "name" : "", "parameterTypes" : [] } ] } ]
mvn clean package
native-image
command which will generate the executable.$GRAALVMDIR/bin/native-image \ --verbose \ --no-server \ -Dio.netty.noUnsafe=true \ -H:ReflectionConfigurationFiles=./reflectconfigs/netty.json \ -H:+ReportUnsupportedElementsAtRuntime \ -Dfile.encoding=UTF-8 \ -jar target/vertx-graalvm-native-image-test-0.0.1-SNAPSHOT.jar
Result vertx-graalvm-native-image-test-0.0.1-SNAPSHOT
executable which we can run.$ ldd vertx-graalvm-native-image-test-0.0.1-SNAPSHOT linux-vdso.so.1 (0x00007ffc65be8000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8e892f0000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8e890d3000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f8e88eb9000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f8e88cb1000) libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f8e88a79000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8e886da000) /lib64/ld-linux-x86-64.so.2 (0x00007f8e8afb7000)
/usr/bin/time -f "\nmaxRSS\t%MkB" java -jar target/vertx-graalvm-native-image-test-0.0.1-SNAPSHOT.jar /usr/bin/time -f "\nmaxRSS\t%MkB" ./vertx-graalvm-native-image-test-0.0.1-SNAPSHOT