Skip to content

Commit

Permalink
Fix xpath factory in multiple threads
Browse files Browse the repository at this point in the history
RISDEV-0000
  • Loading branch information
malte-laukoetter committed Aug 28, 2024
1 parent 472dcf5 commit 290659f
Showing 1 changed file with 12 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

/** Util class that is responsible for parsing a {@link Node}. */
public final class NodeParser {
private static XPathFactory xPathFactory = XPathFactory.newInstance();
// the XPathFactory is not thread safe so every thread gets its own one. It should not be a
// problem that we do not call remove() on it as it can be reused even after returning the thread
// to a ThreadPool.
private static final ThreadLocal<XPathFactory> xPathFactory =
ThreadLocal.withInitial(XPathFactory::newInstance);

private NodeParser() {
// Should not be instantiated as an object
Expand Down Expand Up @@ -45,7 +49,7 @@ public static Optional<String> getValueFromExpression(String xPathExpression, No

// should be invoked on every method call since: An XPath object is not thread-safe and not
// reentrant.
final XPath xPath = xPathFactory.newXPath();
final XPath xPath = xPathFactory.get().newXPath();
String result = (String) xPath.evaluate(xPathExpression, sourceNode, XPathConstants.STRING);
return result.isEmpty() ? Optional.empty() : Optional.of(result);
} catch (XPathExpressionException | NoSuchElementException e) {
Expand Down Expand Up @@ -80,9 +84,12 @@ public static List<Node> getNodesFromExpression(String xPathExpression, Node sou
try {
// should be invoked on every method call since: An XPath object is not thread-safe and not
// reentrant.
final XPath xPath = XPathFactory.newInstance().newXPath();
final NodeList nodeList =
(NodeList) xPath.evaluate(xPathExpression, sourceNode, XPathConstants.NODESET);
(NodeList)
xPathFactory
.get()
.newXPath()
.evaluate(xPathExpression, sourceNode, XPathConstants.NODESET);
return nodeListToList(nodeList);
} catch (XPathExpressionException | NoSuchElementException e) {
throw new XmlProcessingException(e.getMessage(), e);
Expand All @@ -100,8 +107,7 @@ public static List<Node> getNodesFromExpression(String xPathExpression, Node sou
*/
public static Optional<Node> getNodeFromExpression(String xPathExpression, Node sourceNode) {
try {
final XPathFactory xpathfactory = XPathFactory.newInstance();
final XPath xpath = xpathfactory.newXPath();
final XPath xpath = xPathFactory.get().newXPath();
final var result = xpath.evaluate(xPathExpression, sourceNode, XPathConstants.NODE);
if (result instanceof Node node) {
return Optional.of(node);
Expand Down

0 comments on commit 290659f

Please sign in to comment.