I'm writing a plugin for BaseX in Clojure, built via "lein uberjar" with the Clojure interpreter included. For the most part, this works well.
However -- when running via the BaseX HTTP instance, evaluation takes place inside Jetty's thread pool rather than having threads thrown away after a client disconnects.
As loading the plugin loads Clojure's classes through a custom classloader, and throwing away the (AOT-compiled) object instance which acts as the plugin's entry point does not discard the vars placed by Clojure in thread-local space, a classloader leak results with PermGen space being eventually exhausted by multiple instances of the Clojure interpreter.
How can this be resolved? I can make reasonable non-Clojure-specific changes to BaseX's module load/unload mechanism if necessary.
This idea might (or might not) work:
Don't make an uberjar, keep Clojure jars separate;
push Clojure jars up the classloader hierarchy by putting them into the main classpath of BaseX (edit the command line that starts BasexX server, something like java -cp BaseX.jar;clojure.jar org.basex.BaseXServer);
Package your plugin as a jar with just your code in it and rely on the Clojure classes already present in the main classpath.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With