With Asciidoctor rise and its choice to have a single ruby implementation ported to Java and Javascript through bridges, it comes more and more common to have JRuby in your everyday stack, particularly if you adopted the "living documentation" pattern. 

The issue is that JRuby is not "run in all environments" out of the box.

Typically if you use it in short live executions, it is not rare to leak some threads. It is not that hurtful and generally ok to let it leak. But in some cases it will be hurtful, limiting the monitoring and often pollute the logs.

In my case I tracked the issue down to the JIT compiler. The JITCompiler creates an owned executor which creates lazily threads. However running Asciidoctor, you use that in general - and it is rather good so you will not deactivate it.

The issue is that nothing shuts down this thread by default. The simpliest solution is to call tearDown() on the JITCompiler. This can be done with this simple line:

Ruby.getGlobalRuntime().getJITCompiler().tearDown();

Indeed, if you provided a custom JRuby instance you will not use the global runtime instance but your own instance.

Also note that the Ruby instance has the same kind of method you can call if you manually manage the instance. If you let AsciidoctorJ instance manage the Ruby instance then you have to call shutdown() method on the Asciidoctor instance.

I guess JRuby  should likely do it under the hood but in several versions it is not done, so this small workaround will enable you to avoid leaking threads.

Edit: thanks @headius for having fixed that for future JRuby versions. For reference here is the issue and it will be part of JRuby 9.2.6 and later.

From the same author:

In the same category: