polylith
polylith copied to clipboard
Classloader isolation has "leaks"
Describe the bug
Code that uses global JVM thread pools (such as code based on fork/join) can end up loading classes into those threads which then conflict with those same classes loaded into the classloaders poly test creates to run code.
To Reproduce
Exceedingly hard to reproduce(!) and even in some repro cases, it is intermittent. We've managed to mitigate most instances by moving reify calls into the main thread where possible in our code (so no new class instances get loaded in the fork/join thread classloader) but there are places where we just can't do this.
Expected behavior Given the use of isolated classloaders, this is the expected behavior -- it's just problematic. Running tests in a subprocess would resolve this (and other classloader issues) but would make Polylith's test runner logic much more complex I suspect.
Partial Workaround
In addition to reorganizing our code as described above, we have found that changing the *use-context-classloader* binding to false seems to help resolve more cases of this issue. The default is true so I'm not sure why that binding was ever introduced, but at least it provides for a smaller "fix": https://github.com/seancorfield/polylith/commit/5945bd2cf5b36f07a759744f1de702c79970a9b4
Since we made that change on my fork, we have not run into the ClassCastException that the cross-classloader issue described above was causing -- so I think it's a safe change to make and will help others who might be using fork/join code.