JDK-4991857 : throw XPathExpressionException when context is null and expression refers contex
  • Type: Bug
  • Component: xml
  • Sub-Component: javax.xml.xpath
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-02-10
  • Updated: 2017-05-19
  • Resolved: 2007-01-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6 JDK 7
1.4.0 1.4Fixed 6u4Fixed 7Fixed
Related Reports
Duplicate :  
Relates :  
Description
XPath.evaluate(java.lang.String expression, java.lang.Object item, QName returnType)  should throw XPathExpressionException  when 'item' is null and expression refers to the context .

According to the spec :
 In XPath.evaluate(java.lang.String expression,java.lang.Object item,QName returnType)  ,  a null value for item indicates that the expression should be evaluated without a context . In the absence of a context item, simple expressions, such as "1+1", can be evaluated . Any expression that refers to the context will throw an XPathExpressionException

-----------------------------------
java -version
java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b37)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b37, mixed mode)
-----------------------------------
javac Test1.java
java Test1
Test1/checkXPath09() : OK  : 3.0
Test1/checkXPath09() : Failed - expected XPathExpressionException not thrown ::

Testcase - Test1.java
------------------------------------------------------------------------------

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactoryConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Document;

import java.io.File;


public class Test1 {
   
   Document document1 = null;
   
   Test1 () {}
    
    // main()
    public static void main(String[] argv) {
        Test1 test1 = new Test1();
        test1.checkXPath09();
    } 
    // end main()

    // test for XPath.evaluate(java.lang.String expression, java.lang.Object item, QName returnType) , returnType is String
    // item is null , A null value for item indicates that the expression should be evaluated without a context.
    // In the absence of a context item, simple expressions, such as "1+1", can be evaluated.
    // Any expression that refers to the context will throw an XPathExpressionException
    private void checkXPath09() {
    	try{
    	  XPathFactory xpathFactory = XPathFactory.newInstance();
    	  if( xpathFactory instanceof XPathFactory ){
    	     XPath xpath = xpathFactory.newXPath();
	     if ( xpath instanceof XPath ){
		String expression1 = "1+2";
		Double result = (Double)xpath.evaluate(expression1, document1, XPathConstants.NUMBER);
		System.out.println("Test1/checkXPath09() : OK  : "+result);
		String expression2 = "/widgets/widget[@name='a']/@quantity" ;
		String quantity = (String)xpath.evaluate(expression2, document1, XPathConstants.STRING);
		System.out.println("Test1/checkXPath09() : Failed - expected XPathExpressionException not thrown :"+quantity+":");
	     }
    	     else{
    	        System.out.println("checkXPath09() failed - xpath not instance of XPath");
    	     }    	  
    	  }else{
    	      System.out.println(" checkXPath09() failed - creating instance of XPathFactory ");
    	  }  
    	}catch(NullPointerException npe ){
    	  System.out.println(" checkXPathFactory09() - failed ,  NPE thrown ");
    	}catch(XPathFactoryConfigurationException xpfce ){
    	  System.out.println(" checkXPathFactory09() - failed , Default object model not available ");
    	}catch(XPathExpressionException xpee ){
    	  System.out.println(" checkXPathFactory09() - passed , expected XPathExpressionException thrown ");
    	}catch(Exception e){
    	 System.out.println(" Exception thrown - checkXPath09() failed ");
    	}
    }
}


-------------------------------------------------------------------------------
This bug is mostly fixed , now there are only a few contexts 
which don't throw an exception (such as when the context is ".")

lowering the priority of this bug to a P4 given
that it currently is mostly fixed and this bug seems to deal 
with just a corner case .

Comments
EVALUATION I believe I fixed the other cases by disallowing the use of DTM.NULL to initialize an iterator. DTM.NULL shouldn't be used as a context node, and if it is, this indicates a problem in the context (e.g., it being null).
12-01-2007

EVALUATION I've added code to check whether the XPath expression needs a context. If a context is needed for the expression and it is null, then the appropriate exception is thrown.
26-07-2006

EVALUATION I confirmed the bug. A regression JUnit test is in the JAXP RI workspace. It should reproduce quite easily. The problem is that the underlying Xalan XPath code is apparently not written to detect "missing context node" as an error. I know very little about Xalan, but this bug doesn't look like an easy one to me. ###@###.### 2004-02-10
10-02-2004

SUGGESTED FIX I did a little more investiation. Since Xalan uses integer handle to represent a node, we don't have any handly value to denote the absence of the context node. DTM.NULL seems to come close, yet it's already used for so many purposes and it's hard to tell we can safely overload this constant to denote the absence of CN. So we probably have to start from creating another constant, which I'll call "ABSENT". One possible fix is to extend XPathContext and report an error if the methods like getContextNode() return ABSENT. This seems to be the most robust fix, but then there's "getCurrentNodeStack()" method, which exposes the whole raw context node stack, which breaks the whole abstraction. Another potential fix is to intercept DTMIterator.setRoot and detect an error if ABSENT is used as the parameter. There's 14 setRoot impls, so either we modify every one of them (which is error prone since people will forget to check it when adding new setRoot impl), or we have to hack a XPath compiler and wrap DTMIterator by a proxy that checks it. That's my 2 yens. ###@###.### 2004-02-10
10-02-2004