You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2023/03/11 06:49:12 UTC
svn commit: r1908263 - in /poi/trunk: poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/ poi/src/main/java/org/apache/poi/extractor/ poi/src/main/java/org/apache/poi/hssf/record/crypto/ poi/src/main/java/org/apache/poi/hssf/usermodel/ poi/src/...
Author: centic
Date: Sat Mar 11 06:49:12 2023
New Revision: 1908263
URL: http://svn.apache.org/viewvc?rev=1908263&view=rev
Log:
Bug 66521: Add a utility to clear all thread locals
Otherwise some applications may complain about left-over things,
e.g. Tomcat sometimes reports warning logs if Threads are not
cleaned up before being passed back into the global thread-pool.
Added:
poi/trunk/poi/src/main/java/org/apache/poi/util/ThreadLocalUtil.java
poi/trunk/poi/src/test/java/org/apache/poi/util/TestThreadLocalUtil.java
Modified:
poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
poi/trunk/poi/src/main/java/org/apache/poi/extractor/ExtractorFactory.java
poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java
poi/trunk/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
poi/trunk/poi/src/main/java/org/apache/poi/sl/draw/DrawFactory.java
poi/trunk/poi/src/main/java/org/apache/poi/ss/usermodel/DateUtil.java
poi/trunk/poi/src/main/java/org/apache/poi/util/LocaleUtil.java
Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java Sat Mar 11 06:49:12 2023
@@ -66,6 +66,7 @@ import org.apache.poi.sl.usermodel.Slide
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
+import org.apache.poi.util.ThreadLocalUtil;
import org.apache.poi.util.Units;
/**
@@ -92,6 +93,10 @@ public final class HSLFSlideShow extends
INIT, LOADED
}
private static final ThreadLocal<LoadSavePhase> loadSavePhase = new ThreadLocal<>();
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(loadSavePhase::remove);
+ }
// What we're based on
private final HSLFSlideShowImpl _hslfSlideShow;
Modified: poi/trunk/poi/src/main/java/org/apache/poi/extractor/ExtractorFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/extractor/ExtractorFactory.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/extractor/ExtractorFactory.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/extractor/ExtractorFactory.java Sat Mar 11 06:49:12 2023
@@ -38,6 +38,7 @@ import org.apache.poi.poifs.filesystem.E
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.ThreadLocalUtil;
/**
* Figures out the correct POIOLE2TextExtractor for your supplied
@@ -64,6 +65,10 @@ public final class ExtractorFactory {
/** Should this thread prefer event based over usermodel based extractors? */
private static final ThreadLocal<Boolean> threadPreferEventExtractors = ThreadLocal.withInitial(() -> Boolean.FALSE);
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(threadPreferEventExtractors::remove);
+ }
/** Should all threads prefer event based over usermodel based extractors? */
private static Boolean allPreferEventExtractors;
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java Sat Mar 11 06:49:12 2023
@@ -17,6 +17,7 @@
package org.apache.poi.hssf.record.crypto;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.util.ThreadLocalUtil;
public final class Biff8EncryptionKey {
/**
@@ -25,6 +26,10 @@ public final class Biff8EncryptionKey {
* (e.g. {@link HSSFWorkbook}) that need this functionality.
*/
private static final ThreadLocal<String> _userPasswordTLS = new ThreadLocal<>();
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(_userPasswordTLS::remove);
+ }
/**
* Sets the BIFF8 encryption/decryption password for the current thread.
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java Sat Mar 11 06:49:12 2023
@@ -36,6 +36,7 @@ import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.util.Removal;
+import org.apache.poi.util.ThreadLocalUtil;
/**
* High level representation of the style of a cell in a sheet of a workbook.
@@ -123,6 +124,14 @@ public final class HSSFCellStyle impleme
private static final ThreadLocal<Short> lastDateFormat = ThreadLocal.withInitial(() -> Short.MIN_VALUE);
private static final ThreadLocal<List<FormatRecord>> lastFormats = new ThreadLocal<>();
private static final ThreadLocal<String> getDataFormatStringCache = new ThreadLocal<>();
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(() -> {
+ lastDateFormat.remove();
+ lastFormats.remove();
+ getDataFormatStringCache.remove();
+ });
+ }
/**
* Get the contents of the format string, by looking up
@@ -637,7 +646,7 @@ public final class HSSFCellStyle impleme
_format.setFillBackground(bg);
checkDefaultBackgroundFills();
}
-
+
/**
* Set the background fill color represented as a {@link org.apache.poi.ss.usermodel.Color} value.
* <br>
@@ -696,7 +705,7 @@ public final class HSSFCellStyle impleme
_format.setFillForeground(bg);
checkDefaultBackgroundFills();
}
-
+
/**
* Set the foreground fill color represented as a {@link org.apache.poi.ss.usermodel.Color} value.
* <br>
Modified: poi/trunk/poi/src/main/java/org/apache/poi/sl/draw/DrawFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/sl/draw/DrawFactory.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/sl/draw/DrawFactory.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/sl/draw/DrawFactory.java Sat Mar 11 06:49:12 2023
@@ -38,9 +38,14 @@ import org.apache.poi.sl.usermodel.Table
import org.apache.poi.sl.usermodel.TextBox;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextShape;
+import org.apache.poi.util.ThreadLocalUtil;
public class DrawFactory {
private static final ThreadLocal<DrawFactory> defaultFactory = new ThreadLocal<>();
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(defaultFactory::remove);
+ }
/**
* Set a custom draw factory for the current thread.
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/usermodel/DateUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/usermodel/DateUtil.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/usermodel/DateUtil.java [UTF-8] (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/usermodel/DateUtil.java [UTF-8] Sat Mar 11 06:49:12 2023
@@ -36,6 +36,7 @@ import java.util.regex.Pattern;
import org.apache.poi.ss.formula.ConditionalFormattingEvaluator;
import org.apache.poi.util.LocaleUtil;
+import org.apache.poi.util.ThreadLocalUtil;
/**
* Contains methods for dealing with Excel dates.
@@ -546,6 +547,14 @@ public class DateUtil {
private static final ThreadLocal<Integer> lastFormatIndex = ThreadLocal.withInitial(() -> -1);
private static final ThreadLocal<String> lastFormatString = new ThreadLocal<>();
private static final ThreadLocal<Boolean> lastCachedResult = new ThreadLocal<>();
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(() -> {
+ lastFormatIndex.remove();
+ lastFormatString.remove();
+ lastCachedResult.remove();
+ });
+ }
private static boolean isCached(String formatString, int formatIndex) {
return formatIndex == lastFormatIndex.get()
Modified: poi/trunk/poi/src/main/java/org/apache/poi/util/LocaleUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/util/LocaleUtil.java?rev=1908263&r1=1908262&r2=1908263&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/util/LocaleUtil.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/util/LocaleUtil.java Sat Mar 11 06:49:12 2023
@@ -57,6 +57,13 @@ public final class LocaleUtil {
private static final ThreadLocal<TimeZone> userTimeZone = new ThreadLocal<>();
private static final ThreadLocal<Locale> userLocale = new ThreadLocal<>();
+ static {
+ // allow to clear all thread-locals via ThreadLocalUtil
+ ThreadLocalUtil.registerCleaner(() -> {
+ userTimeZone.remove();
+ userLocale.remove();
+ });
+ }
/**
* As time zone information is not stored in any format, it can be
Added: poi/trunk/poi/src/main/java/org/apache/poi/util/ThreadLocalUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/util/ThreadLocalUtil.java?rev=1908263&view=auto
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/util/ThreadLocalUtil.java (added)
+++ poi/trunk/poi/src/main/java/org/apache/poi/util/ThreadLocalUtil.java Sat Mar 11 06:49:12 2023
@@ -0,0 +1,63 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+package org.apache.poi.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Small utility to allow to remove references held in ThreadLocals.
+ *
+ * This is sometimes necessary, e.g. when returning threads into a global
+ * thread pool.
+ *
+ * For each usage of ThreadLocal, a cleaner is registered via
+ * registerCleaner().
+ */
+public class ThreadLocalUtil {
+ private final static List<Runnable> registeredCleaners = new ArrayList<>();
+
+ private ThreadLocalUtil() {
+ }
+
+ /**
+ * Clear {@link ThreadLocal}s of the current thread.
+ *
+ * This can be used to clean out a thread before "returning"
+ * it to a thread-pool or a Web-Container like Tomcat.
+ *
+ * Usually org.apache.xmlbeans.ThreadLocalUtil#clearAllThreadLocals()
+ * should be called as well to clear out some more ThreadLocals which
+ * are created by the XMLBeans library internally.
+ */
+ public static void clearAllThreadLocals() {
+ // run all registered cleaners
+ registeredCleaners.forEach(Runnable::run);
+ }
+
+ /**
+ * Intended for internal use only so other modules of Apache POi
+ * can add cleaners.
+ *
+ * @param cleaner a runnable which clears some thread-local that is
+ * located outside of the "poi" module.
+ */
+ @Internal
+ public static void registerCleaner(Runnable cleaner) {
+ registeredCleaners.add(cleaner);
+ }
+}
Added: poi/trunk/poi/src/test/java/org/apache/poi/util/TestThreadLocalUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/util/TestThreadLocalUtil.java?rev=1908263&view=auto
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/util/TestThreadLocalUtil.java (added)
+++ poi/trunk/poi/src/test/java/org/apache/poi/util/TestThreadLocalUtil.java Sat Mar 11 06:49:12 2023
@@ -0,0 +1,57 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+package org.apache.poi.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.poi.sl.draw.DrawFactory;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+public class TestThreadLocalUtil {
+ private final MemoryLeakVerifier verifier = new MemoryLeakVerifier();
+
+ @AfterEach
+ void tearDown() {
+ verifier.assertGarbageCollected();
+ }
+
+ @Test
+ public void testClearThreadLocalsNoData() {
+ // simply calling it without any thread locals should work
+ ThreadLocalUtil.clearAllThreadLocals();
+ }
+
+ @Test
+ public void testClearThreadLocalsWithData() {
+ DrawFactory factory = new DrawFactory();
+
+ // use the memory leak verifier to ensure that the thread-local is
+ // released after the clear-call below
+ verifier.addObject(factory);
+
+ // store the object in a thread-local
+ DrawFactory.setDefaultFactory(factory);
+
+ // retrieving it works now
+ assertEquals(factory, DrawFactory.getInstance(null));
+
+ // then clear them so that the verifier in tearDown() does not
+ // see the reference any longer
+ ThreadLocalUtil.clearAllThreadLocals();
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org