Saxon-HE 9.3 的 javax.xml.xpath.XPathFactory 提供程序配置文件中的语法错误
Posted
技术标签:
【中文标题】Saxon-HE 9.3 的 javax.xml.xpath.XPathFactory 提供程序配置文件中的语法错误【英文标题】:Syntax error in javax.xml.xpath.XPathFactory provider-configuration file of Saxon-HE 9.3 【发布时间】:2011-12-16 10:14:34 【问题描述】:我在 Mac OS X 和 Saxon-HE 9.3.0.5 上使用 Java SE 6。 ServiceLoader 无法找到 javax.xml.xpath.XPathFactory
的 Saxon 实现。
mac:test2 ludo$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
javax.xml.xpath.XPathFactory
的 newInstance
方法的 javadoc 在查找过程的第 3 点中指出,用于本地化以下实现:
类加载器被要求提供与资源目录 META-INF/services 中的 javax.xml.xpath.XPathFactory 匹配的服务提供者提供者配置文件。有关文件格式和解析规则,请参阅 JAR 文件规范。
JAR 文件规范的Service Provider section 声明:
该文件应包含一个以换行符分隔的唯一具体提供程序类名称列表。
但如果我提取 saxon9he.jar 文件并查看 META-INF 目录,我会看到:
mac:Java ludo$ mkdir test
mac:Java ludo$ cd test
mac:test ludo$ jar fx ../saxon9he.jar
mac:test ludo$ cat META-INF/services/javax.xml.xpath.XPathFactory
net.sf.saxon.xpath.XPathFactoryImpl
http\://java.sun.com/jaxp/xpath/dom: net.sf.saxon.xpath.XPathFactoryImpl
http\://saxon.sf.net/jaxp/xpath/om: net.sf.saxon.xpath.XPathFactoryImpl
第一行是正确的,但我不明白为什么有两行额外的行,看起来这些行给 ServiceLoader 造成了麻烦。我看到了一个测试示例的问题,我写了一个了解用于查找提供程序的机制。我们可以看到 saxon9he.jar 在 CLASSPATH 中。
mac:services ludo$ java ServicesTest
CLASSPATH = ..., /Users/ludo/Library/Java/saxon9he.jar, ...
Service XPathFactory: java.util.ServiceLoader[javax.xml.xpath.XPathFactory]
ServiceConfigurationError: javax.xml.xpath.XPathFactory: jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
感兴趣的线是:
jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
这是 Saxon 的错误还是我的系统不支持的扩展语法?我能做些什么来解决这个问题?
请注意,如果我明确选择实现的类,我可以获得一个工厂。但我想使用服务机制。以下代码有效:
XPathFactory xpf = XPathFactory.newInstance(
XPathFactory.DEFAULT_OBJECT_MODEL_URI,
"net.sf.saxon.xpath.XPathFactoryImpl",
ClassLoader.getSystemClassLoader());
我已经在下面添加了整个 Java 测试程序。
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import javax.xml.xpath.XPathFactory;
public class ServicesTest
public static String getClasspathString()
StringBuilder classpath = new StringBuilder();
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) classLoader).getURLs();
for (int i = 0; i < urls.length - 1; i++)
classpath.append(urls[i].getFile()).append(", ");
if (urls.length > 0)
classpath.append(urls[urls.length - 1].getFile());
return classpath.toString();
public static void availableProviders(ServiceLoader sl)
Iterator it = sl.iterator();
int index = 0;
for (;;)
try
if (!it.hasNext())
break;
index++;
Object o = it.next();
System.out.printf("%03d Concrete class name: %s\n", index, o.getClass().getName());
catch (ServiceConfigurationError e)
System.err.printf("ServiceConfigurationError: %s\n", e.getMessage());
public static void main(String[] args)
System.out.printf("CLASSPATH = %s\n", getClasspathString());
System.out.println();
ServiceLoader<XPathFactory> slXPathFactory = ServiceLoader.load(XPathFactory.class);
System.out.printf("Service XPathFactory: %s\n", slXPathFactory.toString());
availableProviders(slXPathFactory);
【问题讨论】:
您可以使用 'unzip -p /path/to/lib/jarfile.jar META-INF/services/javax.xml.xpath.XPathFactory' 一步将文件直接提取到命令行中 【参考方案1】:我知道这是一个较旧的线程,但this post of mine 可能会对这个问题有所了解。它使用我从未见过的文档中的 -D 参数找到 XPathFactory。
【讨论】:
感谢您的跟进。【参考方案2】:Michael Kay answered the question 在 SourceForge 论坛上。他说:
选择文件格式是为了规避 JDK5 错误。
还有:
实际上,无论如何我都不推荐使用 JAXP 搜索机制。它非常慢,而且它提供了一个不一定适用于您的应用程序的 XPath 引擎。您无法知道您是否获得了 XPath 1.0 或 2.0 实现,而且 API 的定义如此薄弱,以至于您的应用程序几乎不可能与特定的提供者一起工作,除非您首先使用该提供者对其进行了测试。所以即使没有这个错误,我也会避开它。
我认为它回答了问题,即使它没有为问题提供明确的解决方案。所以我们可以通过编写来选择实现:
XPathFactory xpf = XPathFactory.newInstance(
XPathFactory.DEFAULT_OBJECT_MODEL_URI,
"net.sf.saxon.xpath.XPathFactoryImpl",
ClassLoader.getSystemClassLoader());
【讨论】:
在 Saxon 9.5 及更高版本中,此问题已得到解决。如果有人发现自己需要让它与旧版本一起使用并且无法访问调用newInstance
的代码 - 您可以通过从上述 JAR 文件中删除 services
目录来解决问题。这是在错误的线程上关注note。
而在 Saxon 9.6 中,XPath 的 JAXP 解析已被删除 - 请参阅 saxonica.plan.io/issues/1944#note-5以上是关于Saxon-HE 9.3 的 javax.xml.xpath.XPathFactory 提供程序配置文件中的语法错误的主要内容,如果未能解决你的问题,请参考以下文章
org.xml.sax.SAXException:javax.xml.parsers.FactoryConfigurationError:无法创建类 javax.xml.parsers.SAXPars