[
https://issues.apache.org/jira/browse/SLING-7447?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16342113#comment-16342113
]
Konrad Windszus commented on SLING-7447:
----------------------------------------
[~rombert] Thanks for finding and fixing this issue.
I am not sure about throwing exception from static initializers. We are not yet
sure how well this is working for other JREs than OpenJDK/Oracle therefore it
is unclear how often one might experience such an exception. Unfortunately you
only get the real exception logged the first time you try to access this class
but only a very generic NoClassDefFoundException afterwards
(https://bugs.openjdk.java.net/browse/JDK-8051847).
The other alternative is to catch it in the static initializer and store it in
a field. In the constructor you can then check if that exception field is set
and throw it then. That way you prevent those hard to debug
{{NoClassDefFoundException}}s. WDYT?
> Race condition in ThreadLocalCleaner initialization code
> --------------------------------------------------------
>
> Key: SLING-7447
> URL: https://issues.apache.org/jira/browse/SLING-7447
> Project: Sling
> Issue Type: Bug
> Components: Commons
> Affects Versions: Commons Threads 3.2.14
> Reporter: Robert Munteanu
> Assignee: Robert Munteanu
> Priority: Blocker
> Fix For: Commons Threads 3.2.16
>
>
> There is a race condition in the {{ThreadLocalCleaner}} initialization code
> that can lead to the fields not being fully initialized when read.
> The stack trace is similar to
> {noformat}Exception in thread "sling-oak-observation-2"
> java.lang.NullPointerException
> at
> org.apache.sling.commons.threads.impl.ThreadLocalCleaner.copy(ThreadLocalCleaner.java:110)
> at
> org.apache.sling.commons.threads.impl.ThreadLocalCleaner.saveOldThreadLocals(ThreadLocalCleaner.java:230)
> at
> org.apache.sling.commons.threads.impl.ThreadLocalCleaner.<init>(ThreadLocalCleaner.java:155)
> at
> org.apache.sling.commons.threads.impl.ThreadPoolExecutorCleaningThreadLocals.beforeExecute(ThreadPoolExecutorCleaningThreadLocals.java:58)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1139)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> at java.lang.Thread.run(Thread.java:748){noformat}
> Assume that two threads, _T1_ and _T2_ enter the constructor at more or less
> the same time. The following events can then occur, leading to the above
> invalid access
> ||T1||T2||
> |check threadLocalsField (is null)| |
> |invoke initReflectionFields, load threadLocalsField| |
> | | check threadLocalsField (is not null) |
> | | invoke saveOldTreadLocals |
> | | invoke copy |
> At this point, the {{tableField}} field is null since
> {{initReflectionFields}} has not yet completed, which leads to the above NPE.
> _edit_: formatting
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)