我最近获得了Saxon-PE的试用许可证,并希望在Camel中使用这个版本的Saxon。我下载了Saxon-PE-9.6.0.8罐子,并通过maven将它们包含在我的项目中。我使用的是Camel 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] 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个常用帧 by: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] at 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时才会出现此问题。
我可以提供其他可能有用的细节。 提前谢谢。
答案 0 :(得分:2)
Apache Camel 2.16.x不支持Saxon 9.6。我们支持撒克逊人的版本,我们测试的版本是9.5。
Saxon团队改变并破坏了他们的API并不是我们的错。因此,我们无法轻松升级并允许用户使用免费版本9.5运行。
答案 1 :(得分:2)
Saxon基本上有三层接口。第1层是公共API,包括JAXP和XQJ接口以及s9api接口。我们非常努力在各版本之间保持这些兼容性。第2层是“系统编程接口” - 较低级别但集成商经常需要的东西 - 例如NodeInfo和Receiver接口。撒克逊主要版本之间的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组成:一个例子是编译器构建的表达式树的结构。虽然某些第三方应用程序(例如调试器或性能分析器)可能需要访问此类接口,但我们并未尝试使它们从一个主要版本与下一个版本保持兼容。
我认为影响Camel的9.5和9.6之间的特殊变化可能是由于内部Controller类不再作为JAXP Transformer接口的实现类(因此将Transformer转换为Controller不再起作用)。多年来,当控制器执行各种其他功能时,保持控制器这一角色的问题逐渐增加;与此同时,JAXP转换接口(基于XSLT 1.0)完全是Saxon正在做的新事物的外围设备,现在是时候阻止它作为我们内部设计的约束。
我一直认为,我们必须平衡使用户能够轻松前进的需求以及防止代码库中结构衰减(因此不可靠)的需要。随着产品的成熟,稳定性变得越来越重要,但流媒体和模块化编译等新设施在架构上具有破坏性,我们不想停滞不前。
我们随时准备为那些真正遇到困难的用户提供旧版本。