How do I use XPath in a thread-safe and efficient manner?

DavidS :

(A similar question has been asked here, Java XPathFactory thread-safety, but the given answer is incorrect because it ignores the fact that the documentation states that XPathFactory.newInstance() isn't thread-safe.)

From the XPathFactory Javadoc, we have:

The XPathFactory class is not thread-safe. In other words, it is the application's responsibility to ensure that at most one thread is using a XPathFactory object at any given moment. Implementations are encouraged to mark methods as synchronized to protect themselves from broken clients.

XPathFactory is not re-entrant. While one of the newInstance methods is being invoked, applications may not attempt to recursively invoke a newInstance method, even from the same thread.

So from the above quote, I take it that XPathFactory.newInstance() (a static method) should not be called concurrently. It is not thread-safe.

The factory returns XPath objects, which has this XPath Javadoc:

An XPath object is not thread-safe and not reentrant. In other words, it is the application's responsibility to make sure that one XPath object is not used from more than one thread at any given time, and while the evaluate method is invoked, applications may not recursively call the evaluate method.

From the above quote, I take it that XPath.evaluate and XPathExpression.evaluate should not be called concurrently. They are not thread-safe.

Normally when I'm dealing with classes that aren't thread-safe I just use local variables, but because XPathFactory.newInstance() isn't thread-safe, and it's a static method, I'm not sure how to use it safely and efficiently. I guess I could synchronize calls to newInstance, but I worry about performance because my application is an XML message routing application. (In my smoke tests of newInstance it takes ~0.4 milliseconds.)

I can't find any examples of use Java XPath in a thread-safe manner, and I'm not confident I know how to use XPath in a thread-safe but efficient manner. I also have the constraint that I need to use XPath inside a singleton (specifically an Apache Camel Processor).

jaco0646 :

I take it that XPathFactory.newInstance() (a static method) should not be called concurrently. It is not thread-safe.

That documentation could be interpreted differently: thread-safety and reentrancy are distinct attributes, so it is possible for XPathFactory.newInstance() to be thread-safe yet non-reentrant. The word recursively seems key; but the sentence structure is difficult to parse. Without reviewing the code in minute detail, synchronization around any newInstance calls seems the only safe way to use them. Note that Java 9 added the newDefaultInstance method, which appears trivially thread-safe.

I take it that XPath.evaluate and XPathExpression.evaluate should not be called concurrently. They are not thread-safe.

Agreed. The documentation clearly states these methods are neither thread-safe nor reentrant.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=73552&siteId=1