DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6750>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6750 Reusing a Transformer causes a NullPointerException Summary: Reusing a Transformer causes a NullPointerException Product: XalanJ2 Version: CurrentCVS Platform: PC OS/Version: Linux Status: NEW Severity: Critical Priority: Other Component: org.apache.xalan.transformer AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] ENVIRONMENT: * Linux 2.4.7 * JDK: IBMJava2-13 or Sun JDK 1.3.1 or 1.4 * Xalan 2.3.1 (downloaded as "xalan-j_20020227-bin.tar.gz" from "http://xml.apache.org/dist/xalan-j/nightly/2002-02-27") DETAILS: I have a Java app that re-uses a transformer (significant optimization!). The xslt script declares a variable containing a result tree fragment. After enough iterations, I get the following stack dump: javax.xml.transform.TransformerException: java.lang.NullPointerException at java.lang.Throwable.<init>(Throwable.java:96) at java.lang.Exception.<init>(Exception.java:44) at javax.xml.transform.TransformerException.<init>(Unknown Source) at org.apache.xalan.transformer.TransformerImpl.transformNode (TransformerImpl.java:1226) at org.apache.xalan.transformer.TransformerImpl.transform (TransformerImpl.java:634) at org.apache.xalan.transformer.TransformerImpl.transform (TransformerImpl.java:1088) at org.apache.xalan.transformer.TransformerImpl.transform (TransformerImpl.java:1066) at testCase.main(bug.java(Compiled Code)) --------- java.lang.NullPointerException at org.apache.xpath.objects.XRTreeFrag.xstr(XRTreeFrag.java:256) at org.apache.xpath.objects.XObject.dispatchCharactersEvents (XObject.java:187) at org.apache.xpath.Expression.executeCharsToContentHandler (Expression.java:303) at org.apache.xalan.templates.ElemValueOf.execute(ElemValueOf.java:319) at org.apache.xalan.templates.ElemApplyTemplates.transformSelectedNodes (ElemApplyTemplates.java(Compiled Code)) at org.apache.xalan.templates.ElemApplyTemplates.execute (ElemApplyTemplates.java:226) at org.apache.xalan.templates.ElemApplyTemplates.transformSelectedNodes (ElemApplyTemplates.java(Compiled Code)) at org.apache.xalan.templates.ElemApplyTemplates.execute (ElemApplyTemplates.java:226) at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates (TransformerImpl.java:2243) at org.apache.xalan.transformer.TransformerImpl.applyTemplateToNode (TransformerImpl.java:2069) at org.apache.xalan.transformer.TransformerImpl.transformNode (TransformerImpl.java:1171) at org.apache.xalan.transformer.TransformerImpl.transform (TransformerImpl.java:634) at org.apache.xalan.transformer.TransformerImpl.transform (TransformerImpl.java:1088) at org.apache.xalan.transformer.TransformerImpl.transform (TransformerImpl.java:1066) at testCase.main(testCase.java(Compiled Code)) ============================================================================== The problem may be related to Bug 6156 (a problem where-by the variable stack and the cached result tree fragments weren't properly reset)...but since 6156 has been closed, this may be an unrelated issue. Also, it appears that the problem consistently occurs following a garbage collection. I've reproduced the problem using all of the recent sun and ibm jdks. Using the sample testCase I'm attaching, I usually see the problem before the 1000th iteration, but it isn't predictable (which again makes me believe that is it somehow related to garbage collection) Steps to Reproduce =================== testCase.java: import java.io.FileReader; import java.io.StringWriter; import javax.xml.transform.ErrorListener; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; public class testCase { public static void main(String args[]) { if (args.length != 2) { System.err.println("Usage: testCase <xsltScriptFileName> <xsltInputFileName>"); System.exit(-1); } String xsltScriptFileName = args[0]; String xsltInputFileName = args[1]; try { Source xsltSource=new StreamSource(new FileReader (xsltScriptFileName)); TransformerFactory tFactory = TransformerFactory.newInstance(); Templates templates = tFactory.newTemplates(xsltSource); Transformer transformer = templates.newTransformer(); for (int i=0; i<999999; i++) { Source xsltInputSource = new StreamSource(new FileReader(xsltInputFileName)); StringWriter outputBuffer = new StringWriter(); StreamResult xsltResult = new StreamResult(outputBuffer); // if you uncomment the following line the problem goes away // but it's significantly more optimal to reuse the transformer //transformer = templates.newTransformer(); transformer.transform(xsltInputSource, xsltResult); System.err.println("Finished translation #" + i); } } catch (Exception e) { System.err.println("Caught exception + " + e.getMessage()); e.printStackTrace(); System.exit(-1); } } } Sample XSLT Script and XSLT Input ================================== testCaseInput.xslt: <xsl:stylesheet version='1.0' extension-element-prefixes='oeif oeib oeil oeiv oeisql' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> <xsl:output method='text'/> <xsl:variable name="fieldSep"> <xsl:text>'</xsl:text> </xsl:variable> <xsl:variable name="recSep"> <xsl:text> </xsl:text> </xsl:variable> <!-- Detail record --> <xsl:template match="//detail"> <xsl:text>D</xsl:text> <xsl:value-of select="//fdr_no_rep"/> <xsl:value-of select="$fieldSep"/> <xsl:value-of select="$recSep"/> </xsl:template> </xsl:stylesheet> testCaseInput.xml: <document> <detail> <fdr_no_rep>5 </fdr_no_rep> </detail> </document> Running the test case ====================== java testCase input.xsl input.xml Results ======== Finished translation #0 ... Finished translation #xxxx (usually < 1000, but depends on the jvm and the memory allocated to the heap) Caught exception + java.lang.NullPointerException
