0

我们正在构建一个公共组件,它是多个其他项目的依赖项。

我们的项目做了一些 XSLT 转换,我们需要使用 Saxon 引擎。

我们可以完全控制必须使用 Saxon 的特定 XSLT 转换,但无法控制依赖于我们的应用程序的类路径,并且我们不想强迫它们使用 Saxon 进行其他 XML 工作。

我们可以在使用这些工厂提供的 API 进行转换时直接手动调用 Saxon 库。

问题是 Saxon 使用该ServiceLoader模式将自己作为TransformerFactory实现注入,使用 jar 中的此文件:

[saxon.jar]/META-INF/services/javax.xml.transform.TransformerFactory

这意味着将我们用作依赖项的应用程序最终可能会使用 Saxon 而不是其现有的 XML 库。要求这些应用程序更改其代码以调用其特定实现不是一种选择。

有什么方法可以“覆盖” Saxon 库以删除 ServiceLoader 实现?使用 Maven、Java 或其他进程?

4

2 回答 2

0

不幸的是,发现自己使用编写为使用 JAXP 可插入性机制来获取类路径上的任何 XSLT 处理器的库太常见了,但实际上只有当该处理器恰好是 Xalan 时才会起作用。

对于 XPath 场景,这个问题非常严重,以至于 Saxon META-INF 不再将自己声明为 XPath 服务提供者(尽管它仍然实现所有 JAXP 接口)。但对于 XSLT,这种解决方案是不可接受的。

我认为对于大多数情况,将 Java 系统属性 javax.xml.transform.TransformerFactory 设置为 Xalan 的相关类名应该可以解决问题。

于 2016-09-08T13:55:01.040 回答
0

为未来有相同问题的开发人员回答这个问题。

我们无法找到解决此问题的方法。我们考虑编写一个 Maven 插件来META-INF/services/从 JAR 中删除文件,但最终认为这不是一个合适的解决方案。

我们现在处于与开始相同的位置 - 依赖应用程序最终以 Saxon 作为注册提供者,它可能会覆盖它们现有的配置。

对于那些必须使用特定 XSLT 处理器的应用程序,我们要求他们设置系统属性,例如 javax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl

于 2016-09-11T21:49:18.623 回答