You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2018/05/21 18:14:13 UTC

[tika] 02/04: TIKA-2645 - use a pool for SAXParsers -- tika-parsers package

This is an automated email from the ASF dual-hosted git repository.

tallison pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tika.git

commit 64bb30844e0caafff1c9ebac7c8b0c5b512ea81e
Author: tballison <ta...@mitre.org>
AuthorDate: Mon May 21 13:55:56 2018 -0400

    TIKA-2645 - use a pool for SAXParsers -- tika-parsers package
---
 .../java/org/apache/tika/parser/NetworkParser.java   |  7 ++++++-
 .../java/org/apache/tika/parser/ParseContext.java    |  7 +++----
 .../java/org/apache/tika/utils/XMLReaderUtils.java   | 14 ++++++++++++--
 .../java/org/apache/tika/parser/dif/DIFParser.java   |  7 ++++++-
 .../apache/tika/parser/epub/EpubContentParser.java   | 14 ++++++++++----
 .../apache/tika/parser/iwork/IWorkPackageParser.java | 16 ++++++++++++----
 .../microsoft/ooxml/AbstractOOXMLExtractor.java      |  8 +++++++-
 .../ooxml/SXSLFPowerPointExtractorDecorator.java     | 14 ++++++++++++--
 .../microsoft/ooxml/SXWPFWordExtractorDecorator.java |  9 +++++++--
 .../microsoft/ooxml/XSSFExcelExtractorDecorator.java | 12 ++++++++++--
 .../microsoft/ooxml/xps/XPSExtractorDecorator.java   | 20 ++++++++++++++++----
 .../parser/microsoft/ooxml/xwpf/XWPFStylesShim.java  | 12 ++++++++++--
 .../ooxml/xwpf/ml2006/Word2006MLParser.java          |  8 ++++++--
 .../parser/microsoft/xml/AbstractXML2003Parser.java  |  7 ++++++-
 .../apache/tika/parser/ocr/TesseractOCRParser.java   | 11 +++++++++--
 .../tika/parser/odf/OpenDocumentContentParser.java   | 14 +++++++++-----
 .../java/org/apache/tika/parser/xml/XMLParser.java   |  7 ++++++-
 .../tika/detect/TestContainerAwareDetector.java      | 10 +++++++++-
 18 files changed, 156 insertions(+), 41 deletions(-)

diff --git a/tika-core/src/main/java/org/apache/tika/parser/NetworkParser.java b/tika-core/src/main/java/org/apache/tika/parser/NetworkParser.java
index 0f338b7..78b7246 100644
--- a/tika-core/src/main/java/org/apache/tika/parser/NetworkParser.java
+++ b/tika-core/src/main/java/org/apache/tika/parser/NetworkParser.java
@@ -42,6 +42,8 @@ import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import javax.xml.parsers.SAXParser;
+
 public class NetworkParser extends AbstractParser {
 
     private final URI uri;
@@ -124,8 +126,10 @@ public class NetworkParser extends AbstractParser {
 
             TaggedContentHandler tagged = new TaggedContentHandler(
                     new OfflineContentHandler(handler));
+            SAXParser parser = null;
             try {
-                context.getSAXParser().parse(
+                parser = context.acquireSAXParser();
+                parser.parse(
                         stream, new TeeContentHandler(
                                 tagged, new MetaHandler(metadata)));
             } catch (SAXException e) {
@@ -136,6 +140,7 @@ public class NetworkParser extends AbstractParser {
                 throw new TikaException(
                         "Unable to read network parser output", e);
             } finally {
+                context.releaseParser(parser);
                 try {
                     thread.join(1000);
                 } catch (InterruptedException e) {
diff --git a/tika-core/src/main/java/org/apache/tika/parser/ParseContext.java b/tika-core/src/main/java/org/apache/tika/parser/ParseContext.java
index 2a3afcd..6ad85ff 100644
--- a/tika-core/src/main/java/org/apache/tika/parser/ParseContext.java
+++ b/tika-core/src/main/java/org/apache/tika/parser/ParseContext.java
@@ -52,7 +52,6 @@ public class ParseContext implements Serializable {
     /** Serial version UID. */
     private static final long serialVersionUID = -5921436862145826534L;
 
-    private final XMLReaderUtils xmlReaderUtils = new XMLReaderUtils();
     /** Map of objects in this context */
     private final Map<String, Object> context = new HashMap<String, Object>();
 
@@ -153,7 +152,7 @@ public class ParseContext implements Serializable {
         if (context.containsKey(SAXParser.class)) {
             return get(SAXParser.class);
         }
-        return xmlReaderUtils.acquireSAXParser();
+        return XMLReaderUtils.acquireSAXParser();
     }
 
     /**
@@ -163,11 +162,11 @@ public class ParseContext implements Serializable {
      * @param parser
      * @throws TikaException
      */
-    public void releaseParser(SAXParser parser) throws TikaException {
+    public void releaseParser(SAXParser parser) {
         if (context.containsKey(SAXParser.class)) {
             return;
         }
-        xmlReaderUtils.releaseParser(parser);
+        XMLReaderUtils.releaseParser(parser);
     }
 
     /**
diff --git a/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java b/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
index 4ed58b4..a2ad9fc 100644
--- a/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
+++ b/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
@@ -288,20 +288,26 @@ public class XMLReaderUtils implements Serializable {
      */
     public static SAXParser acquireSAXParser()
             throws TikaException {
+        int waiting = 0;
         while (true) {
             SAXParser parser = null;
             try {
                 READ_WRITE_LOCK.readLock().lock();
-                parser = SAX_PARSERS.poll(10, TimeUnit.MILLISECONDS);
+                parser = SAX_PARSERS.poll(100, TimeUnit.MILLISECONDS);
             } catch (InterruptedException e) {
                 throw new TikaException("interrupted while waiting for SAXParser", e);
             } finally {
                 READ_WRITE_LOCK.readLock().unlock();
-
             }
             if (parser != null) {
                 return parser;
             }
+            waiting++;
+            if (waiting > 3000) {
+                //better to get an exception than have permahang by a bug in one of our parsers
+                throw new TikaException("Waited more than 5 minutes for a SAXParser; this could indicate SAXParser leakage.  " +
+                        "Please report this to the Tika team dev@tika.apache.org");
+            }
         }
     }
 
@@ -321,6 +327,10 @@ public class XMLReaderUtils implements Serializable {
             //if there are extra parsers (e.g. after a reset of the pool to a smaller size),
             // this parser will not be added and will then be gc'd
             boolean success = SAX_PARSERS.offer(parser);
+            if (! success) {
+                LOG.warning("SAXParser not taken back into pool.  If you haven't resized the pool, this could " +
+                        "be a sign that there are more calls to 'acquire' than to 'release'");
+            }
         } finally {
             READ_WRITE_LOCK.readLock().unlock();
         }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/dif/DIFParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/dif/DIFParser.java
index 5957508..237fa0b 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/dif/DIFParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/dif/DIFParser.java
@@ -36,6 +36,8 @@ import org.apache.tika.sax.XHTMLContentHandler;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
+import javax.xml.parsers.SAXParser;
+
 public class DIFParser extends AbstractParser {
 
 	/**
@@ -61,8 +63,10 @@ public class DIFParser extends AbstractParser {
 		xhtml.startDocument();
 		xhtml.startElement("p");
 		TaggedContentHandler tagged = new TaggedContentHandler(handler);
+		SAXParser parser = null;
 		try {
-			context.getSAXParser().parse(
+			parser = context.acquireSAXParser();
+			parser.parse(
 					new CloseShieldInputStream(stream),
 					new OfflineContentHandler(new EmbeddedContentHandler(
 							getContentHandler(tagged, metadata, context))));
@@ -70,6 +74,7 @@ public class DIFParser extends AbstractParser {
 			tagged.throwIfCauseOf(e);
 			throw new TikaException("XML parse error", e);
 		} finally {
+			context.releaseParser(parser);
 			xhtml.endElement("p");
 			xhtml.endDocument();
 		}
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/epub/EpubContentParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/epub/EpubContentParser.java
index 83686d9..44d5f72 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/epub/EpubContentParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/epub/EpubContentParser.java
@@ -48,10 +48,16 @@ public class EpubContentParser extends AbstractParser {
             Metadata metadata, ParseContext context)
             throws IOException, SAXException, TikaException {
 
-        SAXParser parser = context.getSAXParser();
-        parser.parse(
-                new CloseShieldInputStream(stream),
-                new OfflineContentHandler(handler));
+        SAXParser parser = null;
+        try {
+            parser = context.acquireSAXParser();
+
+            parser.parse(
+                    new CloseShieldInputStream(stream),
+                    new OfflineContentHandler(handler));
+        } finally {
+            context.releaseParser(parser);
+        }
     }
 
 }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/iwork/IWorkPackageParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/iwork/IWorkPackageParser.java
index 79d82e8..17d30e9 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/iwork/IWorkPackageParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/iwork/IWorkPackageParser.java
@@ -25,6 +25,7 @@ import java.util.HashSet;
 import java.util.Set;
 
 import javax.xml.namespace.QName;
+import javax.xml.parsers.SAXParser;
 
 import org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
@@ -203,10 +204,17 @@ public class IWorkPackageParser extends AbstractParser {
                metadata.add(Metadata.CONTENT_TYPE, type.getType().toString());
                xhtml.startDocument();
                if (contentHandler != null) {
-                  context.getSAXParser().parse(
-                          new CloseShieldInputStream(entryStream),
-                          new OfflineContentHandler(contentHandler)
-                  );
+                   SAXParser parser = null;
+                   try {
+                       parser = context.acquireSAXParser();
+
+                       parser.parse(
+                               new CloseShieldInputStream(entryStream),
+                               new OfflineContentHandler(contentHandler)
+                       );
+                   } finally {
+                       context.releaseParser(parser);
+                   }
                }
                xhtml.endDocument();
             }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java
index 6fd678e..6f4f5a3 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java
@@ -68,6 +68,8 @@ import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
+import javax.xml.parsers.SAXParser;
+
 /**
  * Base class for all Tika OOXML extractors.
  * <p/>
@@ -515,13 +517,17 @@ public abstract class AbstractOOXMLExtractor implements OOXMLExtractor {
                 PackageRelationship relatedPartPackageRelationship = relatedPartPRC.getRelationship(i);
                 try {
                     PackagePart relatedPartPart = parentPart.getRelatedPart(relatedPartPackageRelationship);
+                    SAXParser parser = null;
                     try (InputStream stream = relatedPartPart.getInputStream()) {
-                        context.getSAXParser().parse(stream,
+                        parser = context.acquireSAXParser();
+                        parser.parse(stream,
                                 new OfflineContentHandler(new EmbeddedContentHandler(contentHandler)));
 
                     } catch (IOException|TikaException e) {
                         parentMetadata.add(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING,
                                 ExceptionUtils.getStackTrace(e));
+                    } finally {
+                        context.releaseParser(parser);
                     }
 
                 } catch (InvalidFormatException e) {
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java
index 47d0a07..46cfc98 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java
@@ -49,6 +49,8 @@ import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import javax.xml.parsers.SAXParser;
+
 /**
  * SAX/Streaming pptx extractior
  */
@@ -158,14 +160,18 @@ public class SXSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
             if (commentAuthorsPart == null) {
                 continue;
             }
+            SAXParser parser = null;
             try (InputStream stream = commentAuthorsPart.getInputStream()) {
-                context.getSAXParser().parse(
+                parser = context.acquireSAXParser();
+                parser.parse(
                         new CloseShieldInputStream(stream),
                         new OfflineContentHandler(new XSLFCommentAuthorHandler()));
 
             } catch (TikaException | SAXException | IOException e) {
                 metadata.add(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING,
                         ExceptionUtils.getStackTrace(e));
+            } finally {
+                context.releaseParser(parser);
             }
         }
 
@@ -176,8 +182,10 @@ public class SXSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
 
 //        Map<String, String> hyperlinks = loadHyperlinkRelationships(packagePart);
         xhtml.startElement("div", "class", "slide-content");
+        SAXParser parser = null;
         try (InputStream stream = slidePart.getInputStream()) {
-            context.getSAXParser().parse(
+            parser = context.acquireSAXParser();
+            parser.parse(
                     new CloseShieldInputStream(stream),
                     new OfflineContentHandler(new EmbeddedContentHandler(
                             new OOXMLWordAndPowerPointTextHandler(
@@ -186,6 +194,8 @@ public class SXSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
         } catch (TikaException e) {
             metadata.add(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING,
                     ExceptionUtils.getStackTrace(e));
+        } finally {
+            context.releaseParser(parser);
         }
 
         xhtml.endElement("div");
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXWPFWordExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXWPFWordExtractorDecorator.java
index 287a129..82919d3 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXWPFWordExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXWPFWordExtractorDecorator.java
@@ -47,6 +47,8 @@ import org.apache.tika.utils.ExceptionUtils;
 import org.apache.xmlbeans.XmlException;
 import org.xml.sax.SAXException;
 
+import javax.xml.parsers.SAXParser;
+
 /**
  * This is an experimental, alternative extractor for docx files.
  * This streams the main document content rather than loading the
@@ -187,8 +189,10 @@ public class SXWPFWordExtractorDecorator extends AbstractOOXMLExtractor {
                             XWPFListManager listManager, XHTMLContentHandler xhtml) throws IOException, SAXException {
 
         Map<String, String> linkedRelationships = loadLinkedRelationships(packagePart, true, metadata);
+        SAXParser parser = null;
         try (InputStream stream = packagePart.getInputStream()) {
-            context.getSAXParser().parse(
+            parser = context.acquireSAXParser();
+            parser.parse(
                     new CloseShieldInputStream(stream),
                     new OfflineContentHandler(new EmbeddedContentHandler(
                             new OOXMLWordAndPowerPointTextHandler(
@@ -197,7 +201,8 @@ public class SXWPFWordExtractorDecorator extends AbstractOOXMLExtractor {
         } catch (TikaException e) {
             metadata.add(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING,
                     ExceptionUtils.getStackTrace(e));
-
+        } finally {
+            context.releaseParser(parser);
         }
 
     }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java
index 7e1a7cd..ecae502 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java
@@ -194,11 +194,14 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
         }
 
         //consider adding this back to POI
+        SAXParser parser = null;
         try (InputStream wbData = xssfReader.getWorkbookData()) {
-            SAXParser parser = parseContext.getSAXParser();
+            parser = parseContext.acquireSAXParser();
             parser.parse(wbData, new OfflineContentHandler(new AbsPathExtractorHandler()));
         } catch (InvalidFormatException|TikaException e) {
             //swallow
+        } finally {
+            parseContext.releaseParser(parser);
         }
     }
 
@@ -334,8 +337,11 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
             InputStream sheetInputStream)
             throws IOException, SAXException {
         InputSource sheetSource = new InputSource(sheetInputStream);
+        SAXParser parser = null;
         try {
-            XMLReader sheetParser = parseContext.getXMLReader();
+            parser = parseContext.acquireSAXParser();
+
+            XMLReader sheetParser = parser.getXMLReader();
             XSSFSheetInterestingPartsCapturer handler =
                     new XSSFSheetInterestingPartsCapturer(new XSSFSheetXMLHandler(
                             styles, comments, strings, sheetContentsExtractor, formatter, false));
@@ -348,6 +354,8 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
             }
         } catch (TikaException e) {
             throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage());
+        } finally {
+            parseContext.releaseParser(parser);
         }
     }
 
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xps/XPSExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xps/XPSExtractorDecorator.java
index 689db28..9ef992d 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xps/XPSExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xps/XPSExtractorDecorator.java
@@ -40,6 +40,7 @@ import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import javax.xml.parsers.SAXParser;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
@@ -128,12 +129,15 @@ public class XPSExtractorDecorator extends AbstractOOXMLExtractor {
 
     private void handleDocuments(PackageRelationship packageRelationship,
                                  XHTMLContentHandler xhtml) throws IOException, SAXException, TikaException {
-
+        SAXParser parser = null;
         try (InputStream stream = pkg.getPart(packageRelationship).getInputStream()) {
-            context.getSAXParser().parse(
+            parser = context.acquireSAXParser();
+            parser.parse(
                     new CloseShieldInputStream(stream),
                     new OfflineContentHandler(new EmbeddedContentHandler(
                             new FixedDocSeqHandler(xhtml))));
+        } finally {
+            context.releaseParser(parser);
         }
     }
 
@@ -179,14 +183,18 @@ public class XPSExtractorDecorator extends AbstractOOXMLExtractor {
             }
             String zipPath = (docRef.startsWith("/") ? docRef.substring(1) : docRef);
             if (pkg instanceof ZipPackage) {
+                SAXParser parser = null;
                 try (InputStream stream = getZipStream(zipPath, pkg)) {
-                    context.getSAXParser().parse(
+                    parser = context.acquireSAXParser();
+                    parser.parse(
                             new CloseShieldInputStream(stream),
                             new OfflineContentHandler(new EmbeddedContentHandler(
                                     new PageContentPartHandler(relativeRoot, xhtml))));
 
                 } catch (IOException | TikaException e) {
                     throw new SAXException(new TikaException("IOException trying to read: " + docRef));
+                } finally {
+                    context.releaseParser(parser);
                 }
             } else {
                 throw new SAXException(new TikaException("Package must be ZipPackage"));
@@ -226,8 +234,10 @@ public class XPSExtractorDecorator extends AbstractOOXMLExtractor {
                     if (pagePath.startsWith("/")) {
                         pagePath = pagePath.substring(1);
                     }
+                    SAXParser parser = null;
                     try (InputStream stream = getZipStream(pagePath, pkg)) {
-                        context.getSAXParser().parse(
+                        parser = context.acquireSAXParser();
+                        parser.parse(
                                 new CloseShieldInputStream(stream),
                                 new OfflineContentHandler(
                                         new XPSPageContentHandler(xhtml, embeddedImages)
@@ -235,6 +245,8 @@ public class XPSExtractorDecorator extends AbstractOOXMLExtractor {
                         );
                     } catch (TikaException | IOException e) {
                         throw new SAXException(e);
+                    } finally {
+                        context.releaseParser(parser);
                     }
                 }
 
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/XWPFStylesShim.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/XWPFStylesShim.java
index 0883747..1b5e76b 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/XWPFStylesShim.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/XWPFStylesShim.java
@@ -31,6 +31,8 @@ import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import javax.xml.parsers.SAXParser;
+
 /**
  * For Tika, all we need (so far) is a mapping between styleId and a style's name.
  *
@@ -58,8 +60,14 @@ public class XWPFStylesShim {
     }
 
     private void onDocumentLoad(ParseContext parseContext, InputStream stream) throws TikaException, IOException, SAXException {
-        parseContext.getSAXParser().parse(stream,
-                new OfflineContentHandler(new StylesStripper()));
+        SAXParser parser = null;
+        try {
+            parser = parseContext.acquireSAXParser();
+            parser.parse(stream,
+                    new OfflineContentHandler(new StylesStripper()));
+        } finally {
+            parseContext.releaseParser(parser);
+        }
     }
 
     /**
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/Word2006MLParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/Word2006MLParser.java
index ff8a43d..4b78e6f 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/Word2006MLParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/Word2006MLParser.java
@@ -34,6 +34,8 @@ import org.apache.tika.sax.XHTMLContentHandler;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
+import javax.xml.parsers.SAXParser;
+
 
 public class Word2006MLParser extends AbstractOfficeParser {
 
@@ -55,15 +57,17 @@ public class Word2006MLParser extends AbstractOfficeParser {
                 new XHTMLContentHandler(handler, metadata);
 
         xhtml.startDocument();
-
+        SAXParser parser = null;
         try {
-            context.getSAXParser().parse(
+            parser = context.acquireSAXParser();
+            parser.parse(
                     new CloseShieldInputStream(stream),
                     new OfflineContentHandler(new EmbeddedContentHandler(
                             new Word2006MLDocHandler(xhtml, metadata, context))));
         } catch (SAXException e) {
             throw new TikaException("XML parse error", e);
         } finally {
+            context.releaseParser(parser);
             xhtml.endDocument();
         }
     }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/xml/AbstractXML2003Parser.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/xml/AbstractXML2003Parser.java
index 18e5486..8ad4fe2 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/xml/AbstractXML2003Parser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/xml/AbstractXML2003Parser.java
@@ -40,6 +40,8 @@ import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
+import javax.xml.parsers.SAXParser;
+
 
 public abstract class AbstractXML2003Parser extends AbstractParser {
 
@@ -94,8 +96,10 @@ public abstract class AbstractXML2003Parser extends AbstractParser {
         xhtml.startDocument();
 
         TaggedContentHandler tagged = new TaggedContentHandler(xhtml);
+        SAXParser parser = null;
         try {
-            context.getSAXParser().parse(
+            parser = context.acquireSAXParser();
+            parser.parse(
                     new CloseShieldInputStream(stream),
                     new OfflineContentHandler(new EmbeddedContentHandler(
                             getContentHandler(tagged, metadata, context))));
@@ -103,6 +107,7 @@ public abstract class AbstractXML2003Parser extends AbstractParser {
             tagged.throwIfCauseOf(e);
             throw new TikaException("XML parse error", e);
         } finally {
+            context.releaseParser(parser);
             xhtml.endDocument();
         }
     }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java
index 478fed7..7d53976 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java
@@ -592,10 +592,17 @@ public class TesseractOCRParser extends AbstractParser implements Initializable
         if (parseContext == null) {
             parseContext = new ParseContext();
         }
-        SAXParser parser = parseContext.getSAXParser();
+
         xhtml.startElement("div", "class", "ocr");
-        parser.parse(is, new OfflineContentHandler(new HOCRPassThroughHandler(xhtml)));
+        SAXParser parser = null;
+        try {
+            parser = parseContext.acquireSAXParser();
+            parser.parse(is, new OfflineContentHandler(new HOCRPassThroughHandler(xhtml)));
+        } finally {
+            parseContext.releaseParser(parser);
+        }
         xhtml.endElement("div");
+
     }
 
     /**
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java
index 18ebc49..da71755 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java
@@ -596,11 +596,15 @@ public class OpenDocumentContentParser extends AbstractParser {
         DefaultHandler dh = new OpenDocumentElementMappingContentHandler(handler, MAPPINGS);
 
 
-        SAXParser parser = context.getSAXParser();
-        parser.parse(
-                new CloseShieldInputStream(stream),
-                new OfflineContentHandler(
-                        new NSNormalizerContentHandler(dh)));
+        SAXParser parser = context.acquireSAXParser();
+        try {
+            parser.parse(
+                    new CloseShieldInputStream(stream),
+                    new OfflineContentHandler(
+                            new NSNormalizerContentHandler(dh)));
+        } finally {
+            context.releaseParser(parser);
+        }
     }
 
 }
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/xml/XMLParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/xml/XMLParser.java
index b17058d..328b711 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/xml/XMLParser.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/xml/XMLParser.java
@@ -37,6 +37,8 @@ import org.apache.tika.sax.XHTMLContentHandler;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
+import javax.xml.parsers.SAXParser;
+
 /**
  * XML parser.
  */
@@ -68,8 +70,10 @@ public class XMLParser extends AbstractParser {
         xhtml.startElement("p");
 
         TaggedContentHandler tagged = new TaggedContentHandler(handler);
+        SAXParser parser = null;
         try {
-            context.getSAXParser().parse(
+            parser = context.acquireSAXParser();
+            parser.parse(
                     new CloseShieldInputStream(stream),
                     new OfflineContentHandler(new EmbeddedContentHandler(
                             getContentHandler(tagged, metadata, context))));
@@ -77,6 +81,7 @@ public class XMLParser extends AbstractParser {
             tagged.throwIfCauseOf(e);
             throw new TikaException("XML parse error", e);
         } finally {
+            context.releaseParser(parser);
             xhtml.endElement("p");
             xhtml.endDocument();
         }
diff --git a/tika-parsers/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java b/tika-parsers/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java
index b5198b1..f11e224 100644
--- a/tika-parsers/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java
+++ b/tika-parsers/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java
@@ -31,6 +31,7 @@ import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.tika.MultiThreadedTikaTest;
 import org.apache.tika.Tika;
 import org.apache.tika.config.TikaConfig;
+import org.apache.tika.exception.TikaException;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
@@ -38,6 +39,7 @@ import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MimeTypes;
 import org.apache.tika.parser.iwork.iwana.IWork13PackageParser;
 import org.apache.tika.utils.XMLReaderUtils;
+import org.junit.After;
 import org.junit.Test;
 
 /**
@@ -48,6 +50,12 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
     private final MimeTypes mimeTypes = tikaConfig.getMimeRepository();
     private final Detector detector = new DefaultDetector(mimeTypes);
 
+    @After
+    public void tearDown() throws TikaException {
+        //make sure to reset pool size because it is being randomly resized during the tests
+        XMLReaderUtils.setPoolSize(10);
+    }
+
     private void assertTypeByData(String file, String type) throws Exception {
        assertTypeByNameAndData(file, null, type);
     }
@@ -455,7 +463,7 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
         };
         int numThreads = 1;
         XMLReaderUtils.setPoolSize(numThreads);
-        testDetector(detector, numThreads, 20, filter, numThreads*2);
+        testDetector(detector, numThreads, 20, filter, numThreads * 2);
     }
 
     @Test

-- 
To stop receiving notification emails like this one, please contact
tallison@apache.org.