-
Enhancement
-
Resolution: Done
-
Major
-
None
-
None
-
None
The current implementation of `PeriodicRecovery.suspendScan(boolean, boolean)` directly invokes `doWork()`, running the recovery cycle directly on the calling thread. Although `PeriodicRecovery` can handle an invocation of `doWork()` by foreign threads (e.g. threads from an integrating party), the recovery logic modifies the context class loader of the executing thread. This operation is unsafe and can lead to permission errors when executed outside of a controlled environment. In particular, when the Security Manager is active and the calling thread belongs to a restricted pool like the `ForkJoinPool`, the action fails with a `java.lang.SecurityException: setContextClassLoader` wrapped in a `java.util.concurrent.CompletionException` (this specific example is valid for JDK 17). In general, this issue occurs anytime the calling thread doesn't have permissions to change its context class loader.
To prevent this issue, we are changing the mechanism in `PeriodicRecovery.suspendScan(boolean, boolean)`:
- The calling thread no longer executes `doWork()` directly
- instead, it will wait the end of an extra recovery cycle, which is normally executed by `PeriodicRecovery`'s dedicated background thread