Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

(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).

like image 776
DavidS Avatar asked Jan 03 '19 16:01

DavidS


People also ask

Is XPath thread-safe?

An XPath expression is not thread-safe and not reentrant. In other words, it is the application's responsibility to make sure that one XPathExpression 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.

Which of the following options is thread-safe?

Answer: Since String is immutable in Java, it's inherently thread-safe.

What is thread-safe code?

Thread safety is a computer programming concept applicable to multi-threaded code. Thread-safe code only manipulates shared data structures in a manner that ensures that all threads behave properly and fulfill their design specifications without unintended interaction.


2 Answers

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.

like image 57
jaco0646 Avatar answered Oct 31 '22 05:10

jaco0646


You could abandon the JAXP/DOM world and move to Saxon, where multithreading is much more carefully incorporated into the API design:

  • Unlike the DOM, the Saxon native tree implementations are thread-safe once document building is complete. You also get XPath 3.1 as a bonus.

  • An XPathCompiler is thread-safe once configured using its setter methods

  • An XPathExpression (created by compiling an expression using an XPathCompiler) is thread-safe (it can be executed concurrently in multiple threads)

  • An XPathSelector (formed by loading an XPathExpression) is not thread-safe; it should only be evaluated once.

like image 34
Michael Kay Avatar answered Oct 31 '22 04:10

Michael Kay