是什么导致了 Camel XSLT 处理中的 NullPointerException?
What could be causing NullPointerException in Camel XSLT processing?
在过去的几周里,我一直在尝试使用聚合后的 XSLT 处理来处理骆驼路线上的间歇性问题。它是间歇性的,因为虽然它经常引发此异常,但我可以重新 运行 几秒钟后失败的数据提取和处理,它通常会成功。我还没有找到任何始终失败的数据。
我假设聚合导致了问题,但我终究无法理解为什么。我认为这可能是我使用的自定义聚合 bean,所以我用 XSLTAggreationStrategy 替换了它,但它仍然间歇性地给出这个问题,无论是在进一步转换聚合 XML 时,还是只是将它写到文件中时.
这是在 Apache-Karaf 环境中执行的,我加载了 Camel-Saxon 2.21.2 和 Apache ServiceMix Saxon-HE 9.8.0。8_1 包已加载。
感谢观看。
简化的堆栈跟踪是:
...
Caused by: [java.lang.NullPointerException -
null]java.lang.NullPointerException
at net.sf.saxon.dom.DOMNodeWrapper$ChildEnumeration.skipFollowingTextNodes(DOMNodeWrapper.java:1149)
at net.sf.saxon.dom.DOMNodeWrapper$ChildEnumeration.next(DOMNodeWrapper.java:1178)
at net.sf.saxon.tree.util.Navigator$EmptyTextFilter.next(Navigator.java:1078)
at net.sf.saxon.tree.util.Navigator$AxisFilter.next(Navigator.java:1039)
at net.sf.saxon.tree.util.Navigator$AxisFilter.next(Navigator.java:1017)
at net.sf.saxon.expr.parser.ExpressionTool.effectiveBooleanValue(ExpressionTool.java:643)
at net.sf.saxon.expr.Expression.effectiveBooleanValue(Expression.java:532)
at net.sf.saxon.pattern.PatternWithPredicate.matches(PatternWithPredicate.java:141)
at net.sf.saxon.trans.Mode.searchRuleChain(Mode.java:570)
at net.sf.saxon.trans.Mode.getRule(Mode.java:476)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1041)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:281)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:241)
at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:239)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1057)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:281)
at net.sf.saxon.expr.instruct.ApplyTemplates.process(ApplyTemplates.java:237)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:431)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:373)
at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:239)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1057)
at net.sf.saxon.Controller.transformDocument(Controller.java:2080)
at net.sf.saxon.Controller.transform(Controller.java:1903)
at org.apache.camel.builder.xml.XsltBuilder.process(XsltBuilder.java:141)
at org.apache.camel.impl.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:103)
at org.apache.camel.component.xslt.XsltEndpoint.onExchange(XsltEndpoint.java:138) ...
在 9.8.0.8 中,class net.sf.saxon.dom.DOMNodeWrapper
只有 1144 行,因此显示第 1178 行的堆栈跟踪表明存在某种版本控制问题。
class DOMNodeWrapper
是在9.5中首次引入的(以前称为NodeWrapper
),行号与当前9.5源代码中的行号仅差一个,所以我怀疑您加载的是 9.5 分支的某些 sub-release。堆栈跟踪中的其他行号也与 9.5 一致。
这当然不能解释问题,但它可能会提供一些线索。
我的直觉是,自 9.5 以来的这些年里,我们可能已经修复了一个 multi-threading 错误。 DOM 不是 thread-safe,因此 Saxon 非常注意同步其访问。 Saxon bug https://saxonica.plan.io/issues/2376 解决了这个问题。在 9.5 分支上,这首先在维护版本 9.5.1.11 中修复,因此您可能没有该补丁。我认为调查为什么要加载旧版本的 Saxon 会很有用,另一个有用的角度是发现它到底是哪个版本(静态方法 net.sf.saxon.Version.getProductVersion()
将为您提供此信息。)
顺便说一句,如果您使用 multi-threaded 访问 DOM 树,那么您应该问问自己这是否是个好主意。 Saxon 对 DOM 的访问即使在最好的情况下也很慢(与 JDOM 和 XOM 相比,更不用说 Saxon 的原生树模型了),缺乏线程安全性和同步需求使其成为一个multi-threaded 应用程序中的选择非常糟糕。
另外,请注意 Saxon 可以同步它自己对 DOM 的访问,但它不能与可能也在使用 DOM 的 third-party 代码同步。
在过去的几周里,我一直在尝试使用聚合后的 XSLT 处理来处理骆驼路线上的间歇性问题。它是间歇性的,因为虽然它经常引发此异常,但我可以重新 运行 几秒钟后失败的数据提取和处理,它通常会成功。我还没有找到任何始终失败的数据。
我假设聚合导致了问题,但我终究无法理解为什么。我认为这可能是我使用的自定义聚合 bean,所以我用 XSLTAggreationStrategy 替换了它,但它仍然间歇性地给出这个问题,无论是在进一步转换聚合 XML 时,还是只是将它写到文件中时.
这是在 Apache-Karaf 环境中执行的,我加载了 Camel-Saxon 2.21.2 和 Apache ServiceMix Saxon-HE 9.8.0。8_1 包已加载。
感谢观看。
简化的堆栈跟踪是:
... Caused by: [java.lang.NullPointerException - null]java.lang.NullPointerException at net.sf.saxon.dom.DOMNodeWrapper$ChildEnumeration.skipFollowingTextNodes(DOMNodeWrapper.java:1149) at net.sf.saxon.dom.DOMNodeWrapper$ChildEnumeration.next(DOMNodeWrapper.java:1178) at net.sf.saxon.tree.util.Navigator$EmptyTextFilter.next(Navigator.java:1078) at net.sf.saxon.tree.util.Navigator$AxisFilter.next(Navigator.java:1039) at net.sf.saxon.tree.util.Navigator$AxisFilter.next(Navigator.java:1017) at net.sf.saxon.expr.parser.ExpressionTool.effectiveBooleanValue(ExpressionTool.java:643) at net.sf.saxon.expr.Expression.effectiveBooleanValue(Expression.java:532) at net.sf.saxon.pattern.PatternWithPredicate.matches(PatternWithPredicate.java:141) at net.sf.saxon.trans.Mode.searchRuleChain(Mode.java:570) at net.sf.saxon.trans.Mode.getRule(Mode.java:476) at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1041) at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:281) at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:241) at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:239) at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1057) at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:281) at net.sf.saxon.expr.instruct.ApplyTemplates.process(ApplyTemplates.java:237) at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:431) at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:373) at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:239) at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1057) at net.sf.saxon.Controller.transformDocument(Controller.java:2080) at net.sf.saxon.Controller.transform(Controller.java:1903) at org.apache.camel.builder.xml.XsltBuilder.process(XsltBuilder.java:141) at org.apache.camel.impl.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:103) at org.apache.camel.component.xslt.XsltEndpoint.onExchange(XsltEndpoint.java:138) ...
在 9.8.0.8 中,class net.sf.saxon.dom.DOMNodeWrapper
只有 1144 行,因此显示第 1178 行的堆栈跟踪表明存在某种版本控制问题。
class DOMNodeWrapper
是在9.5中首次引入的(以前称为NodeWrapper
),行号与当前9.5源代码中的行号仅差一个,所以我怀疑您加载的是 9.5 分支的某些 sub-release。堆栈跟踪中的其他行号也与 9.5 一致。
这当然不能解释问题,但它可能会提供一些线索。
我的直觉是,自 9.5 以来的这些年里,我们可能已经修复了一个 multi-threading 错误。 DOM 不是 thread-safe,因此 Saxon 非常注意同步其访问。 Saxon bug https://saxonica.plan.io/issues/2376 解决了这个问题。在 9.5 分支上,这首先在维护版本 9.5.1.11 中修复,因此您可能没有该补丁。我认为调查为什么要加载旧版本的 Saxon 会很有用,另一个有用的角度是发现它到底是哪个版本(静态方法 net.sf.saxon.Version.getProductVersion()
将为您提供此信息。)
顺便说一句,如果您使用 multi-threaded 访问 DOM 树,那么您应该问问自己这是否是个好主意。 Saxon 对 DOM 的访问即使在最好的情况下也很慢(与 JDOM 和 XOM 相比,更不用说 Saxon 的原生树模型了),缺乏线程安全性和同步需求使其成为一个multi-threaded 应用程序中的选择非常糟糕。
另外,请注意 Saxon 可以同步它自己对 DOM 的访问,但它不能与可能也在使用 DOM 的 third-party 代码同步。