Bug #2412
closedNPE evaluating pattern containing global variable in streaming mode
100%
Description
From saxon-help list:
Saxon-EE 9.6.0.6J gives me a strange NullPointerException, which only
occurs in streaming mode. If I run the same document without streaming
mode, everything works// as expected. The issue seems to be related to
using a parameter in an XPath expression.
Below is a stylesheet that illustrates the problem. I want to iterate
over all nodes whose name matches the parameter.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:param name="node-name" required="yes"/>
<xsl:mode streamable="yes"/>
<xsl:template match="/">
<xsl:for-each select="//node()[name() = $node-name]">
<found/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Here is an example input document:
<a>abc</a>
<b>def</b>
<a>abc</a>
<b>def</b>
Here is how I run Saxon from command line:
java -cp SaxonEE9-6-0-6J/saxon9ee.jar net.sf.saxon.Transform -s:in.xml
-xsl:stylesheet.xsl -o:out.xml node-name=record
I use a Linux system. My Java Runtime Engine is (output of "java -version"):
openjdk version "1.8.0_45"
OpenJDK Runtime Environment (build 1.8.0_45-b14)
OpenJDK 64-Bit Server VM (build 25.45-b02, mixed mode)
If I remove the xsl:mode element in the stylesheet, I get the expected
result (). In streaming mode, I get the
following exception:
java.lang.NullPointerException
at
net.sf.saxon.expr.XPathContextMajor.getTargetComponent(XPathContextMajor.java:778)
at
net.sf.saxon.expr.XPathContextMinor.getTargetComponent(XPathContextMinor.java:554)
at
net.sf.saxon.expr.GlobalVariableReference.evaluateVariable(GlobalVariableReference.java:93)
at
com.saxonica.ee.optim.IndexedLookupExpression.effectiveBooleanValue(IndexedLookupExpression.java:266)
at
net.sf.saxon.pattern.PatternWithPredicate.matchesPredicate(PatternWithPredicate.java:119)
at
net.sf.saxon.pattern.PatternWithPredicate.matchesBeneathAnchor(PatternWithPredicate.java:138)
at
com.saxonica.ee.stream.watch.PatternWatch.matchesNode(PatternWatch.java:33)
at
com.saxonica.ee.stream.watch.WatchManager.startElement(WatchManager.java:208)
at
net.sf.saxon.event.StartTagBuffer.startContent(StartTagBuffer.java:220)
at
net.sf.saxon.event.ReceivingContentHandler.startElement(ReceivingContentHandler.java:356)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379)
at
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:605)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3138)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:441)
at net.sf.saxon.event.Sender.send(Sender.java:172)
at net.sf.saxon.Controller.transformStream(Controller.java:2319)
at net.sf.saxon.Controller.transform(Controller.java:1666)
at
net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:547)
at net.sf.saxon.Transform.processFile(Transform.java:1056)
at net.sf.saxon.Transform.doTransform(Transform.java:659)
at net.sf.saxon.Transform.main(Transform.java:80)
java.lang.NullPointerException
at
net.sf.saxon.expr.XPathContextMajor.getTargetComponent(XPathContextMajor.java:778)
at
net.sf.saxon.expr.XPathContextMinor.getTargetComponent(XPathContextMinor.java:554)
at
net.sf.saxon.expr.GlobalVariableReference.evaluateVariable(GlobalVariableReference.java:93)
at
com.saxonica.ee.optim.IndexedLookupExpression.effectiveBooleanValue(IndexedLookupExpression.java:266)
at
net.sf.saxon.pattern.PatternWithPredicate.matchesPredicate(PatternWithPredicate.java:119)
at
net.sf.saxon.pattern.PatternWithPredicate.matchesBeneathAnchor(PatternWithPredicate.java:138)
at
com.saxonica.ee.stream.watch.PatternWatch.matchesNode(PatternWatch.java:33)
at
com.saxonica.ee.stream.watch.WatchManager.startElement(WatchManager.java:208)
at
net.sf.saxon.event.StartTagBuffer.startContent(StartTagBuffer.java:220)
at
net.sf.saxon.event.ReceivingContentHandler.startElement(ReceivingContentHandler.java:356)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379)
at
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:605)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3138)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:441)
at net.sf.saxon.event.Sender.send(Sender.java:172)
at net.sf.saxon.Controller.transformStream(Controller.java:2319)
at net.sf.saxon.Controller.transform(Controller.java:1666)
at
net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:547)
at net.sf.saxon.Transform.processFile(Transform.java:1056)
at net.sf.saxon.Transform.doTransform(Transform.java:659)
at net.sf.saxon.Transform.main(Transform.java:80)
Fatal error during transformation: java.lang.NullPointerException: (no
message)
This issue also does not occur if I remove the parameter and replace it
with a string literal ('record') in the XPath expression.
Updated by Michael Kay over 9 years ago
Test case added to XSLT3 test suite as si-for-each-801; problem reproduced.
Updated by Michael Kay over 9 years ago
I think there's a significant problem exposed by this test case.
Essentially the streaming for-each select expression is being treated as a pattern to be matched against nodes as they arrive from the streamed input. All such patterns are being matched using the same XPathContext object, specifically, the one held by the WatchManager. But where patterns contain references to external components such as functions and global variables, these references (which might be cross-package references) need to be resolved using a "current component" set to the component in which the external reference appears; that is, a different context each time.
The failure is occurring because in this particular case, currentComponent in the context has not been initialized.
Updated by Michael Kay over 9 years ago
- Status changed from New to In Progress
A patch which will work for 9.6 is for GlobalVariableReference.evaluateVariable() to use the non-packaging branch if currentComponent is unknown. This basically handles all cases except those where multiple packages are in use with overridden global variables - and that case is already only partially supported in 9.6.
I've committed this patch on the 9.6 branch.
But a more comprehensive solution is needed for 9.7.
Updated by Michael Kay over 9 years ago
- Status changed from In Progress to Resolved
For the time being, I've added the same fix to 9.7 as to 9.6. I have also added a test override-v-004 to test that global variables referenced in a match pattern can be overridden in another module.
Updated by O'Neil Delpratt over 9 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in version set to 9.6.0.7
Bug fix applied in the Saxon 9.6.0.7 maintenance release.
Updated by O'Neil Delpratt almost 9 years ago
- Applies to branch 9.6 added
- Fix Committed on Branch 9.6 added
- Fixed in Maintenance Release 9.6.0.7 added
Please register to edit this issue