Hello, Please see what I propose to solve problem with many allocated DocumentBuilders (Sorry, but I propose revert back changes proposed by Sanjiva). Other classes were DocumentBuilder is used can be easily adopted in the same way as Call is.
Best regards, Pavel
Index: XMLParserUtils.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/util/xml/XMLParserUtils.java,v retrieving revision 1.6 diff -u -r1.6 XMLParserUtils.java --- XMLParserUtils.java 28 Oct 2002 16:37:02 -0000 1.6 +++ XMLParserUtils.java 29 Oct 2002 15:38:07 -0000 @@ -2,7 +2,7 @@ * The Apache Software License, Version 1.1 * * - * Copyright (c) 2000 The Apache Software Foundation. All rights + * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -18,7 +18,7 @@ * distribution. * * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: + * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, @@ -26,7 +26,7 @@ * * 4. The names "SOAP" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this - * software without prior written permission. For written + * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", @@ -57,7 +57,8 @@ package org.apache.soap.util.xml; -import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; @@ -72,8 +73,9 @@ * @author Matthew J. Duftler ([EMAIL PROTECTED]) */ public class XMLParserUtils { + private static DocumentBuilderFactory dbf = null; - private static HashMap docBuilderTable = new HashMap (); + private static List allocatedBuildersList = new ArrayList(10); static { // Create a default instance. @@ -91,7 +93,7 @@ * @param factoryClassName the fully-qualified name of a class * that implemements DocumentBuilderFactory. If this argument * is null, the default (platform-specific) implementation is - * used. Basically, if this argument is not null, the + * used. Basically, if this argument is not null, the * javax.xml.parsers.DocumentBuilderFactory system property * is set (with the specified value) before the * DocumentBuilderFactory.newInstance() method is invoked. @@ -121,32 +123,59 @@ and reused to create any number of DocumentBuilder instances with the same configuration options. */ + allocatedBuildersList.clear(); } /** - * Use this method to get a JAXP document builder. - * This method creates a namespace aware, nonvalidating + * Use this method to get a JAXP document builder. + * This method creates a namespace aware, nonvalidating * instance of the XML parser. * - * @return DocumentBuilder an instance of a document builder, + * @return DocumentBuilder an instance of a document builder, * or null if a ParserConfigurationException was thrown. */ synchronized public static DocumentBuilder getXMLDocBuilder() throws IllegalArgumentException { - // if a document builder has already been created for this thread - // then just reuse that. otherwise create a new one and remember it. - Thread t = Thread.currentThread (); - DocumentBuilder db = (DocumentBuilder) docBuilderTable.get (t); - if (db != null) { - return db; - } else { try { - db = dbf.newDocumentBuilder(); - docBuilderTable.put (t, db); - return db; + return dbf.newDocumentBuilder(); } catch (ParserConfigurationException pce) { throw new IllegalArgumentException(pce.toString()); } - } } + + + /** + * Use this method to get a JAXP document builder. + * This method either returns a previosly allocated DocumentBuilder + * or creates a namespace aware, nonvalidating + * instance of the XML parser. + * + * @return DocumentBuilder an instance of a document builder, + * or null if a ParserConfigurationException was thrown. + */ + synchronized public static DocumentBuilder getXMLDocBuilderFromPool() { + // First check if we have DocBuider available + DocumentBuilder builder = null; + int size = allocatedBuildersList.size(); + if ( size > 0) { + builder = (DocumentBuilder)allocatedBuildersList.get(size-1); + allocatedBuildersList.remove(size-1); + } else + // Not available - create a new DocumentBuilder + builder = XMLParserUtils.getXMLDocBuilder(); + + return builder; + } + + /** + * Return a JAXP document builder, previosly allocated by method + * getXMLDocBuilderFromPool() for further reuse + * + * @param builder a DocumentBuilder to release + */ + synchronized public static void returnDocumentBuilderToPool(DocumentBuilder +builder) { + if (builder != null) + allocatedBuildersList.add(builder); + } + } Index: Call.java =================================================================== RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/rpc/Call.java,v retrieving revision 1.18 diff -u -r1.18 Call.java --- Call.java 18 Oct 2002 13:36:00 -0000 1.18 +++ Call.java 29 Oct 2002 15:38:56 -0000 @@ -87,7 +87,6 @@ */ public class Call extends RPCMessage { - private DocumentBuilder xdb; private SOAPMappingRegistry smr = null; private SOAPTransport st = null;; private int to = 0; @@ -149,7 +148,7 @@ { this.st = st; } - + public SOAPTransport getSOAPTransport() { return st; @@ -157,16 +156,16 @@ /** * Set timeout in our MessageContext. - * + * * @param value the maximum amount of time, in milliseconds */ public void setTimeout (int value) { to = value; } - + /** * Get timeout from our MessageContext. - * + * * @return value the maximum amount of time, in milliseconds */ public int getTimeout () { @@ -188,7 +187,7 @@ public void setUseDocumentBuilder(boolean useDocumentBuilder) { this.useDocumentBuilder = useDocumentBuilder; } - + /** * Add a MIME BodyPart. * @@ -294,7 +293,7 @@ st = new SOAPHTTPConnection(); // set the timeout - if (to != 0 && st instanceof SOAPHTTPConnection) + if (to != 0 && st instanceof SOAPHTTPConnection) ((SOAPHTTPConnection)st).setTimeout(to); // Post the call envelope. @@ -349,7 +348,7 @@ { throw new SOAPException(Constants.FAULT_CODE_CLIENT, "Parsing error, response was:\n" +e.getMessage(), - e); + e); } catch (IOException e) { @@ -364,8 +363,8 @@ * parser plus a transformation. */ private Document parsePayload(String payload) throws IOException, SAXException { - InputSource input = new InputSource(new StringReader(payload)); - if (!useDocumentBuilder) { + InputSource input = new InputSource(new StringReader(payload)); + if (!useDocumentBuilder) { try { // If classes required for transformation are all present, use that method Class domResultClass = Class.forName("javax.xml.transform.dom.DOMResult"); @@ -375,14 +374,14 @@ Class sourceClass = Class.forName("javax.xml.transform.Source"); Class resultClass = Class.forName("javax.xml.transform.Result"); - Object output = domResultClass.newInstance(); + Object output = domResultClass.newInstance(); Object source = saxSourceClass.newInstance(); // Create factory and use to create transformer Method method = transformerFactoryClass.getDeclaredMethod("newInstance", new Class[]{}); - Object xformFactory = method.invoke(null, new Object[]{}); + Object xformFactory = method.invoke(null, new Object[]{}); method = transformerFactoryClass.getDeclaredMethod("newTransformer", new Class[]{}); - Object idTransform = method.invoke(xformFactory, new Object[]{}); + Object idTransform = method.invoke(xformFactory, new Object[]{}); // Set input source for SAX source method = saxSourceClass.getDeclaredMethod("setInputSource", new Class[]{InputSource.class}); @@ -397,7 +396,7 @@ // If all has worked, we return here; for exceptions, // we fall through to the DOM parser. - return (Document) method.invoke(output, new Object[]{}); + return (Document) method.invoke(output, new Object[]{}); } catch (ClassNotFoundException e) { } catch (NoSuchMethodException e) { } catch (InvocationTargetException e) { @@ -406,9 +405,16 @@ } } + DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilderFromPool(); + Document doc = null; // if the DOM parser hasn't been created yet, do it now - if (xdb == null) - xdb = XMLParserUtils.getXMLDocBuilder(); - return xdb.parse(input); + try { + doc = xdb.parse(input); + } + finally { + XMLParserUtils.returnDocumentBuilderToPool(xdb); + } + return doc; + } }
-- To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org>