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) {

Reply via email to