【问题标题】:Using Saxon-PE with Apache Camel, Error Pre-Loading Saxon Classes将 Saxon-PE 与 Apache Camel 一起使用,预加载 Saxon 类时出错
【发布时间】:2016-04-08 13:56:05
【问题描述】:

我最近获得了 Saxon-PE 的试用许可证,并希望在 Camel 中使用此版本的 Saxon。我下载了 Saxon-PE-9.6.0.8 jar 并通过 maven 将它们包含到我的项目中。我正在使用骆驼 2.16.0。 我已经尝试了很多方法,但我通过使用 Camel 的“?transformerFactory=...”选项并将其传递给 Saxon 的 ProfessionalTransformerFactoryImpl 取得了最大的进展,它在我的 Spring 配置中注册为 bean。

启动我的应用程序时,使用 xslt 转换的路由初始化失败,并显示以下堆栈跟踪:

原因:java.lang.IllegalStateException: 预加载 Saxon 时出错 类。确保类路径中有撒克逊人,并且 classloader 可以加载以下两个类: net.sf.saxon.event.Receiver,net.sf.saxon.serialize.MessageWarner。在 org.apache.camel.builder.xml.XsltBuilder.doStart(XsltBuilder.java:618) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.util.ServiceHelper.startService(ServiceHelper.java:74) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.component.xslt.XsltEndpoint.doStart(XsltEndpoint.java:396) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:3219) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.impl.DefaultCamelContext.doAddService(DefaultCamelContext.java:1209) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.impl.DefaultCamelContext.addService(DefaultCamelContext.java:1170) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.impl.DefaultCamelContext.addService(DefaultCamelContext.java:1166) ~[camel-core-2.16.0.jar:2.16.0] 在 org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:583) ~[camel-core-2.16.0.jar:2.16.0] ...省略了38个常用框架导致 通过:java.lang.NoSuchMethodException: net.sf.saxon.jaxp.TransformerImpl.setMessageEmitter(net.sf.saxon.event.Receiver) 在 java.lang.Class.getMethod(Class.java:1786) ~[na:1.8.0_45] 在 org.apache.camel.builder.xml.XsltBuilder.doStart(XsltBuilder.java:616) ~[camel-core-2.16.0.jar:2.16.0] ...省略了47个常用框架

问题在于 JAXP TransformerImpl 中不存在 setMessageEmitter() 方法。

如果有人有任何将 Saxon-PE/EE 与骆驼集成的经验,我将不胜感激。我需要 Saxon-PE 才能使用我的 xsl 样式表中的外部函数调用。以前,在同一个项目中,我使用 Saxon-HE(通过 camel-saxon maven 依赖项)没有任何问题。只有在切换到 Saxon-PE 时才会出现此问题。

我可以提供任何其他可能有帮助的细节。 提前致谢。

【问题讨论】:

    标签: java apache-camel saxon


    【解决方案1】:

    Saxon 基本上有三层接口。第 1 层是公共 API,包括 JAXP 和 XQJ 接口以及 s9api 接口。我们非常努力地保持这些在不同版本之间的兼容性。第 2 层是“系统编程接口”——有点低级的东西,但集成商经常需要它——例如 NodeInfo 和 Receiver 接口。 Saxon 主要版本之间的 SPI 通常会有一些小的变化(例如 9.5 到 9.6,或 9.6 到 9.7)。对于维护版本(例如 9.5.0.7 到 9.5.0.8),我们会努力避免任何不兼容的更改。即使在主要版本中,我们也会尽量避免对 SPI 进行无偿更改,但如果在架构上需要,我们将进行更改。例如,在 9.6 之前,我们在 Receiver 接口中将位置信息(系统 ID、行号和列号)公开为全局唯一整数。但是在 XSLT 3.0 和 Saxon 9.7 中引入了单独编译的包,这意味着这种设计变得不可行,所以我们改为传递一个 Location 对象。尽管这些更改很小,但它们足以确保使用 Saxon 并偏离稳定的公共 API 的应用程序通常至少需要重新编译才能使用新的 Saxon 版本。

    第三层由内部 API 组成:一个例子是编译器构建的表达式树的结构。尽管某些第三方应用程序(例如调试器或性能分析器)可能需要访问此类接口,但我们不会尝试使它们在一个主要版本与下一个主要版本之间保持兼容。

    我认为 9.5 和 9.6 之间影响 Camel 的特定变化可能是由于内部 Controller 类不再充当 JAXP Transformer 接口的实现类(因此将 Transformer 转换为 Controller 不再起作用)。多年来,在执行各种其他职能的同时,维持该角色的控制者的问题逐渐增加;同时,JAXP 转换接口(牢固地基于 XSLT 1.0)对于 Saxon 正在做的新事物越来越外围,现在是时候防止它成为我们内部设计的约束了。

    我一直认为,我们必须平衡让用户更容易前进的需求和防止代码库中的结构性衰退(以及因此的不可靠性)的需求。随着产品的成熟,稳定性变得越来越重要,但流式传输和模块化编译等新功能在架构上具有颠覆性,我们不想停滞不前。

    我们随时准备为在前进过程中遇到真正困难的用户提供旧版本。

    【讨论】:

      【解决方案2】:

      Apache Camel 2.16.x 不支持 Saxon 9.6。我们支持我们测试的 Saxon 版本,fair 为 9.5。

      Saxon 团队更改并破坏了他们的 API 并不是我们的错。因此我们无法轻松升级并允许用户使用免费版本 9.5 运行。

      【讨论】:

      • 谢谢。我已联系 Saxonica 要求 9.5 罐。希望能解决它。
      • 完美,我确认从 9.6 切换到 9.5.1-3 我们的 Saxon-HE 测试依赖项使我们的 xslt 转换在 Junit 中再次工作。
      • “Saxon 团队更改并破坏了他们的 API,这不是我们的错”...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-21
      • 2012-06-28
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      相关资源
      最近更新 更多