将 Saxon-PE 与 Apache Camel 一起使用,预加载 Saxon 类时出错 [英] Using Saxon-PE with Apache Camel, Error Pre-Loading Saxon Classes

查看:54
本文介绍了将 Saxon-PE 与 Apache Camel 一起使用,预加载 Saxon 类时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have recently obtained a trial license for Saxon-PE and wish to use this version of Saxon within Camel. I downloaded the Saxon-PE-9.6.0.8 jars and have included them into my project via maven. I am using Camel 2.16.0. I have tried many approaches to this, but I have made the most headway by using Camel's "?transformerFactory=..." option and passing it Saxon's ProfessionalTransformerFactoryImpl, which is registered as a bean in my Spring config.

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

When starting my application, the route initialization with the xslt transformation fails with the following stack trace:

Caused by: java.lang.IllegalStateException: Error pre-loading Saxon类.确保类路径上有撒克逊人,并且类加载器可以加载以下两个类: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个常用帧

Caused by: java.lang.IllegalStateException: Error pre-loading Saxon classes. Make sure you have saxon on the classpath, and the classloader can load the following two classes: net.sf.saxon.event.Receiver, net.sf.saxon.serialize.MessageWarner. at org.apache.camel.builder.xml.XsltBuilder.doStart(XsltBuilder.java:618) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.util.ServiceHelper.startService(ServiceHelper.java:74) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.component.xslt.XsltEndpoint.doStart(XsltEndpoint.java:396) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:3219) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.impl.DefaultCamelContext.doAddService(DefaultCamelContext.java:1209) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.impl.DefaultCamelContext.addService(DefaultCamelContext.java:1170) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.impl.DefaultCamelContext.addService(DefaultCamelContext.java:1166) ~[camel-core-2.16.0.jar:2.16.0] at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:583) ~[camel-core-2.16.0.jar:2.16.0] ... 38 common frames omitted Caused by: java.lang.NoSuchMethodException: net.sf.saxon.jaxp.TransformerImpl.setMessageEmitter(net.sf.saxon.event.Receiver) at java.lang.Class.getMethod(Class.java:1786) ~[na:1.8.0_45] at org.apache.camel.builder.xml.XsltBuilder.doStart(XsltBuilder.java:616) ~[camel-core-2.16.0.jar:2.16.0] ... 47 common frames omitted

问题是 JAXP TransformerImpl 中不存在 setMessageEmitter() 方法.

The issue is that the setMessageEmitter() method does not exist in the JAXP TransformerImpl.

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

If anybody has any experience integrating Saxon-PE/EE with camel, I would appreciate any input. I need Saxon-PE in order to make use of external function calls from my xsl stylesheets. Previously, in the same project, I have used with Saxon-HE (via the camel-saxon maven dependency) without any trouble. It is only upon switching to Saxon-PE that this problem occurs.

我可以提供可能有帮助的任何其他详细信息.提前致谢.

I can provide any other details that might help. Thanks in advance.

推荐答案

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

Saxon basically has three tiers of interfaces. Tier 1 is public APIs, including the JAXP and XQJ interfaces and the s9api interface. We try very hard to keep these compatible across releases. Tier 2 is "system programming interfaces" - things that are a little lower-level, but which are frequently needed by integrators - examples are the NodeInfo and Receiver interfaces. There are usually a few small changes to SPIs between Saxon major releases (e.g. 9.5 to 9.6, or 9.6 to 9.7). With maintenance releases (e.g. 9.5.0.7 to 9.5.0.8) we try very hard to avoid any incompatible changes. We try to avoid gratuitous changes to SPIs even at major releases, but we will make a change if it is architecturally necessary. For example, until 9.6 we exposed location information (system id, line and column number) in the Receiver interface as a globally unique integer. But the introduction of separately-compiled packages in XSLT 3.0, and hence in Saxon 9.7, meant that this design became unworkable, so we switched to passing a Location object instead. Although these changes are minor, they are enough to ensure that an application that uses Saxon, and strays outside the stable public APIs, typically needs to at least be recompiled to work with a new Saxon version.

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

The third tier consists of internal APIs: an example is the structure of the expression tree built by the compiler. Although some third party applications (e.g. debuggers or performance profilers) may need to access such interfaces, we make no attempt to keep them compatible from one major release to the next.

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

I think the particular change between 9.5 and 9.6 that affects Camel is probably due to the fact that the internal Controller class no longer serves as the implementation class of the JAXP Transformer interface (so casting Transformer to Controller no longer works). The problems of maintaining the Controller in this role, when it also performed various other functions, had slowly increased over the years; at the same time the JAXP transformation interface (which is firmly based on XSLT 1.0) is increasingly peripheral to the new things Saxon is doing and the time had come to prevent it acting as a constraint on our internal design.

我一直认为,我们必须平衡使用户更容易前进的需求和防止代码库中的结构衰退(从而导致不可靠性)的需求.随着产品的成熟,稳定性变得越来越重要,但流和模块化编译等新设施在架构上具有破坏性,我们不想停滞不前.

I have always taken the view that we have to balance the need to make it easy for users to move forward and the need to prevent structural decay (and hence unreliability) in the code base. As the product has matured, stability has become increasingly important, but new facilities like streaming and modular compilation are architecturally disruptive, and we don't want to stand still.

我们随时准备向确实有困难的用户提供旧版本.

We are always prepared to make old releases available to users who have genuine difficulties moving forward.

这篇关于将 Saxon-PE 与 Apache Camel 一起使用,预加载 Saxon 类时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆