This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch feature/improve-logging in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git
commit 31d21b73412d593ae6aaaa055d1e52cd8948383a Author: Konrad Windszus <[email protected]> AuthorDate: Wed Dec 27 12:23:26 2023 +0100 SLING-12212 Improve logging when TheadPoolExecutorCleaningThreadLocals cannot be initialized --- .../sling/commons/threads/impl/DefaultThreadPool.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java b/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java index 0287eba..1bcbe7d 100644 --- a/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java +++ b/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java @@ -27,6 +27,7 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import org.apache.sling.commons.threads.ModifiableThreadPoolConfig; import org.apache.sling.commons.threads.ThreadPool; @@ -154,7 +155,7 @@ public class DefaultThreadPool handler, new LoggingThreadLocalChangeListener()); } catch (RuntimeException | Error e) { - logger.warn("Unsupported JRE, cannot register ThreadPoolExecutorCleaningThreadLocals due to '{}', fall back to regular ThreadPoolExecutor", e.getMessage(), e); + logThreadPoolExecutorCleaningThreadLocalsException(e); this.executor = new ThreadPoolExecutor(this.configuration.getMinPoolSize(), this.configuration.getMaxPoolSize(), this.configuration.getKeepAliveTime(), @@ -166,6 +167,19 @@ public class DefaultThreadPool this.logger.info("Thread pool [{}] initialized.", name); } + private void logThreadPoolExecutorCleaningThreadLocalsException(Throwable t) { + Throwable rootCause = Stream.iterate(t, Throwable::getCause) + .filter(element -> element.getCause() == null) + .findFirst().orElse(t); + String msg = String.format( + "Unsupported JRE, cannot register ThreadPoolExecutorCleaningThreadLocals due to '{}', fall back to regular ThreadPoolExecutor.%n" + + "In most cases this can be fixed by using Java option \"--add-opens java.base/java.lang=org.apache.sling.commons.threads\".%n" + + "ThreadPoolExecutorCleaningThreadLocals is crucial to clean up thread locals in case application code missed to do that via ThreadLocal.remove()!", + rootCause.getMessage()); + logger.warn(msg); + logger.debug("Cannot create ThreadPoolExecutorCleaningThreadLocals", t); + } + private static class LoggingThreadLocalChangeListener implements ThreadLocalChangeListener { @Override public void changed(Mode mode, Thread thread, ThreadLocal<?> threadLocal, Object value) {
