blog podcast

Quarkus, Netty and OpenSSL

Quarkus is built on top of Netty which is a library that can provide you with high performant asynchronous network code on JVM. One of the features that Netty supports is SSL termination. Now SSL, being cryptography, is actually quite demanding on the processor. For this reason Netty has provided two solutions. One that is using the JDK implementation for SSL and one that is utilizing JNI to call OpenSSL on your machine.

The JNI solution is roughly four times as efficient on the CPU as the pure JDK version. The tricky thing is that it can only be used if JNI has access to a native OpenSSL library that it can call.

Now here comes some of the tricky parts for Quarkus. First of, you can use OpenSSL in quarkus when you are not running your application in Native. You can do this by making a OpenSSL library available, for example by adding this dependency to your project:

    implementation 'io.netty:netty-tcnative-boringssl-static:2.0.39.Final'

But for native to work you would need to ensure that the library (which is part of the resources of the mentioned dependency) is not optimized away in compilation. You would also need to make sure that the JNI classes are not rationalized away by Quarkus “closed world” assumptions (Quarkus assumes reflections are not used and only classes called in the code it can see is needed, other stuff is removed). Is this possible to do? Well, it might have been, but when you did into the code in Quarkus you’ll actually see that the developers have decided that OpenSSL is simply not supported. You’ll find the following in extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/graal/NettySubstitutions.java

/**
 * Hardcode io.netty.handler.ssl.OpenSsl as non-available
 */
@TargetClass(className = "io.netty.handler.ssl.OpenSsl")
final class Target_io_netty_handler_ssl_OpenSsl {

    @Alias
    @RecomputeFieldValue(kind = Kind.FromAlias)
    private static Throwable UNAVAILABILITY_CAUSE = new RuntimeException("OpenSsl unsupported on Quarkus");

There will be good reasons for why this has been done. When I was trying to play around with getting the OpenSSL to work I noticed that quarkus wasn’t very fond of adding custom JNIConfigurationFiles settings, as can be seen in this issue.