Investigating the nature of the leak proper --
Any loadable module which, either directly or through its libraries, sets up thread-local data containing strong references to instances of objects whose classes were loaded via a plugin classloader will in turn have references to its classloader (presently a distinct JarLoader instance for each query) from the thread finalization routine.
Bringing this into the context of my own usage for the Java interface -- the very purpose and intent of the SvnKitWrapper module is to do one-time initialization only once, stuff context away in thread-local space, and be able to efficiently leverage that context during future queries. There's still a serious bug in the BaseX Java module interface that needs to be fixed (in terms of not reusing classloaders or module instances, mooting any benefit from this kind of state caching), but let's ignore that for the moment and try to figure out what we can do differently in terms of the Java module API to make this kind of thing possible in the future.
I'd like to propose that the specification for Java modules require them to put only weak references in thread-local space, and include a call which BaseX can make when initially loading a module which will return a strong reference to any state-local data, which the BaseX module interface will contract to hold until that module is uninstalled.
This way, we can ensure that no strong references are held in the thread-local state (preventing module unload), while ensuring that strong references *are* held as long as a module is installed to permit caching state.
Thoughts?