I'm trying to use an XPathFactory to evaluate an expression in a Java application. But I'm getting a Saxon-specific error. At one time I used Saxon for some functionality, and to do that I had to set a system property:
System.setProperty("javax.xml.xpath.XPathFactory:" + NamespaceConstant.OBJECT_MODEL_SAXON,
"net.sf.saxon.xpath.XPathFactoryImpl");
XPathFactory xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);
However, now I just want to do some XML processing using the default DOM (org.w3c.dom.Document) and process with xpath, so Saxon isn't needed. But when I try to create an XPathFactory I still get the Saxon error message:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: net/sf/saxon/lib/EnvironmentVariableResolver
at net.sf.saxon.xpath.XPathFactoryImpl.<init>(XPathFactoryImpl.java:26)
...
I even tried "resetting" the system property:
System.setProperty("javax.xml.xpath.XPathFactory:",
"org.apache.xpath.jaxp.XPathFactoryImpl");
XPathFactory factory = XPathFactory.newInstance();
And
System.setProperty("javax.xml.xpath.XPathFactory:",
"http://java.sun.com/jaxp/xpath/dom");
XPathFactory factory = XPathFactory.newInstance();
But that doesn't help, I still get the same error message.
How do I get rid of this in order to use the default XPathFactory again? (this has worked fine before I tried using Saxon)
As a workaround, you can explicitly instanciate the JDK factory (or Xerces's or Saxon's).
import org.apache.xpath.jaxp.XPathFactoryImpl
// import com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl
// import net.sf.saxon.xpath.XPathFactoryImpl
...
XPathFactory factory = new XPathFactoryImpl();
If possible, prefer the real Xerces implementation to the one found in the JDK. It is more reliable.
I have encounter the same question. Even no "System.setProperty" is called, jaxp will load saxon's xpath engine as default implementation provding saxon jar is on the classpath. Reference: namespace-unaware XPath expression fails if Saxon is on the CLASSPATH.
My solution: call saxon directly as: " XPathFactory _xFactory = new net.sf.saxon.xpath.XPathFactoryImpl();" and add jaxen-xxx.jar and xercesImpl.jar before saxon9e.jar on the classpath. Everything else remains its original state without call "System.setProperty". This works for me.
I also test another method as follows:
System.setProperty("javax.xml.xpath.XPathFactory:" +XPathConstants.DOM_OBJECT_MODEL, "net.sf.saxon.xpath.XPathFactoryImpl");
XPathFactory xFactory = XPathFactory.newInstance(XPathConstants.DOM_OBJECT_MODEL);
System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME +":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI, " org.apache.xpath.jaxp.XPathFactoryImpl");
XPathFactory xFactory2 = XPathFactory.newInstance();
System.out.println(xFactory.toString());
System.out.println(xFactory2.toString());
The output: net.sf.saxon.xpath.XPathFactoryImpl@71623278 com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl@768b970c Since Jaxp use apache's jaxen as its default xpath implementation, this method should work tool. Since JAXP uses
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With