[ http://issues.apache.org/jira/browse/XALANJ-2101?page=all ]
Brian Minchau updated XALANJ-2101: ---------------------------------- Fix Version: 2.7 > DTM Usage in a multithreaded environment > ---------------------------------------- > > Key: XALANJ-2101 > URL: http://issues.apache.org/jira/browse/XALANJ-2101 > Project: XalanJ2 > Type: Bug > Components: DTM > Versions: 2.5 > Environment: All platforms, JDK1.4.2_05, xalan with xerces 2.5 > Reporter: Rony Zoghby > Assignee: Henry Zongaro > Priority: Critical > Fix For: 2.7 > > Hi, > We have a multi-threaded memory intensive application with extensive use of > xsl processing. > Performance is critical so we're using a caching mechanism of xalan DTM > structures > so not to build the DTM everytime. > Based on the code below, we would like to know if our usage is thread safe, > as the DTM > structure is an internal xalan structure. > The code we're using (a structure of the code rather than the actual code) is > the following: > /* > get the xsl stylesheet templates object from our templates cache using the > templatesKey > The templates key is for us the content of the stylesheet > */ > Templates templates=null; > synchronized(templatesCache){ > templates=cache.getTemplates(templatesKey); > if(templates==null){ > synchronized(transformerFactory){ > templates=transformerFactory.newTemplates(...); > } > cache.addTemplates(templatesKey, templates); > } > } > > /* > Each xsl stylesheet templates object has a pool of xsl transformers, so not > to create > a transformer each time. > */ > TransformerImpl > transformerImpl=templates.getTransformerPool().getTransfomer(); > try{ > transformerImpl.setURIResolver(...); > > /* > Get the DTM structure from our dtmCache, if not in cache create it and > put it in cache > We have a DTM cache so that we don't create the DTM each time and we > didn't want to use a DOM > object because the xalan library transforms it internally to DTM. The > dtmKey is the content > of the XML document that we want to execute the XSL formula on. > */ > DTM dtm=null; > synchronized(dtmCache){ > dtm=(org.apache.xml.dtm.DTM)dtmCache.getDTM(dtmKey); > if(dtm==null){ > /* > We also have a DOMParser cache so that we don't create one each > time. > Here we're building the DTM for the first time and adding it to > our DTM cache > */ > DOMParser domParser=(DOMParser)domParserPool.getDomParser(); > try{ > domParser.setEntityResolver(...); > InputSource inputSource=new InputSource(new StringReader(...)); > domParser.parse(inputSource); > Node node=domParser.getDocument(); > DOMSource domSource=new DOMSource(node); > dtm=transformerImpl.getXPathContext().getDTM(domSource, false, > transformerImpl, true, true); > dtmCache.addDTM(dtmKey, dtm); > }finally{ > domParserPool.release(domParser); > } > }else{ > /* > We found the DTM in our DTM cache, so we're setting it in the > manager to be able to use that > DTM for our execution > */ > > DTMManagerDefault > dtmManagerDefault=(DTMManagerDefault)transformerImpl.getXPathContext().getDTMManager(); > dtmManagerDefault.addDTM(dtm, > dtmManagerDefault.getFirstFreeDTMID()); > } > } > transformerImpl.setQuietConflictWarnings(true); > /* > We set the parameters for xsl:param > */ > transformerImpl.setParameter(strParameterKey, strParameterValue); > /* > We execute the XSL stylesheet using the DTM from our DTM cache > */ > transformerImpl.transformNode(dtm.getDocument(), new > SAXResult(xslQueryHandler)); > }finally{ > /* We reset the objects for next execution*/ > transformerImpl.clearParameters(); > transformerImpl.reset(); > templates.getTransformerPool().release(transformerImpl); > } > Using this code, we faced a problem where two same XMLs executed a foreach > xsl command > at the same time on the same DTM and we had the xalan library hanging (kill > -QUIT > on the java process) in: > at > org.apache.xml.dtm.ref.DTMDefaultBaseTraversers$IndexedDTMAxisTraverser.getNextIndexed(Unknown > Source) > at > org.apache.xml.dtm.ref.DTMDefaultBaseTraversers$DescendantTraverser.first(Unknown > Source) > at org.apache.xpath.axes.DescendantIterator.nextNode(Unknown Source) > at org.apache.xpath.axes.LocPathIterator.asNode(Unknown Source) > at org.apache.xpath.axes.DescendantIterator.asNode(Unknown Source) > at org.apache.xpath.axes.LocPathIterator.bool(Unknown Source) > at org.apache.xpath.XPath.bool(Unknown Source) > at org.apache.xalan.templates.ElemChoose.execute(Unknown Source) > at > org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(Unknown > Source) > at org.apache.xalan.templates.ElemIf.execute(Unknown Source) > at > org.apache.xalan.templates.ElemForEach.transformSelectedNodes(Unknown Source) > at org.apache.xalan.templates.ElemForEach.execute(Unknown Source) > So we guessed that the DTM cannot be shared by two threads, and we're > thinking of adding > a synchronized(dtm) just before doing the transformNode. Is this safe? > - Can we also use this code to sequentially execute different XSL stylesheets > on the same DTM? > - Is there another safe way of using XML documents caching, DomParser > pooling, etc ...? > Thank you. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]