java Saxon-HE 9.3 的 javax.xml.xpath.XPathFactory 提供程序配置文件中的语法错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7914915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Syntax error in javax.xml.xpath.XPathFactory provider-configuration file of Saxon-HE 9.3
提问by Ludovic Kuty
I am using Java SE 6 on Mac OS X and Saxon-HE 9.3.0.5. The ServiceLoader is not able to find the Saxon implementation of javax.xml.xpath.XPathFactory
.
我在 Mac OS X 和 Saxon-HE 9.3.0.5 上使用 Java SE 6。ServiceLoader 无法找到javax.xml.xpath.XPathFactory
.
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)
The javadoc of the newInstance
method of javax.xml.xpath.XPathFactory
states in point 3 of the lookup procedure to localize an implementation that:
查找过程第 3 点newInstance
中javax.xml.xpath.XPathFactory
状态方法的 javadoc,用于本地化实现:
The class loader is asked for service provider provider-configuration files matching javax.xml.xpath.XPathFactory in the resource directory META-INF/services. See the JAR File Specification for file format and parsing rules.
类加载器需要在资源目录 META-INF/services 中提供与 javax.xml.xpath.XPathFactory 匹配的服务提供者提供者配置文件。有关文件格式和解析规则,请参阅 JAR 文件规范。
The Service Provider sectionof the JAR File Specification states that:
JAR 文件规范的服务提供者部分指出:
The file should contain a newline-separated list of unique concrete provider-class names.
该文件应包含一个以换行符分隔的唯一具体提供者类名称列表。
But if I extract the saxon9he.jar file and look into the META-INF directory, I see:
但是如果我提取 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
The first line is correct but I can't see why there are two extra lines and it looks like those lines are causing trouble to ServiceLoader. I saw the problem with a test example that I wrote the understand the mecanism used to find a provider. We can see that saxon9he.jar is in the CLASSPATH.
第一行是正确的,但我不明白为什么有两行额外的行,看起来这些行给 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
The line of interest is:
感兴趣的线路是:
jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
Is it a bug of Saxon or an extended syntax not supported by my system ? What could i do to solve the issue ?
是 Saxon 的错误还是我的系统不支持的扩展语法?我能做些什么来解决这个问题?
Note that if I explicitly choose the class for the implementation, I can get a factory. But I want to use the Services mechanism. The following code works:
请注意,如果我为实现明确选择类,我可以获得一个工厂。但我想使用服务机制。以下代码有效:
XPathFactory xpf = XPathFactory.newInstance(
XPathFactory.DEFAULT_OBJECT_MODEL_URI,
"net.sf.saxon.xpath.XPathFactoryImpl",
ClassLoader.getSystemClassLoader());
I have added the whole Java test program below.
我在下面添加了整个 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);
}
}
采纳答案by Ludovic Kuty
Michael Kay answered the questionon a SourceForge forum. He said that:
Michael Kay在 SourceForge 论坛上回答了这个问题。他说过:
The format of the file was chosen to circumvent a JDK5 bug.
选择文件格式是为了规避 JDK5 错误。
And also that:
还有:
Actually, I wouldn't recommend using the JAXP search mechanism anyway. It's very slow, and it delivers an XPath engine that won't necessarily work with your application. You have no way of knowing whether you get an XPath 1.0 or 2.0 implementation back, and the API is so weakly defined that there's very little chance your application will work with a particular provider unless you have tested it with that provider first. So even without this bug, I would steer clear of it.
实际上,无论如何我都不推荐使用 JAXP 搜索机制。它非常慢,而且它提供的 XPath 引擎不一定适用于您的应用程序。您无法知道您获得的是 XPath 1.0 还是 2.0 实现,而且 API 的定义如此薄弱以至于您的应用程序与特定提供者一起工作的可能性很小,除非您首先使用该提供者对其进行了测试。所以即使没有这个错误,我也会避开它。
I think it answers the question even if it does not provide an explicit fix for the problem. So we could chose the implementation by writing:
我认为即使它没有为问题提供明确的解决方案,它也能回答这个问题。所以我们可以通过编写来选择实现:
XPathFactory xpf = XPathFactory.newInstance(
XPathFactory.DEFAULT_OBJECT_MODEL_URI,
"net.sf.saxon.xpath.XPathFactoryImpl",
ClassLoader.getSystemClassLoader());
回答by Erik Ostermueller
I know this is an older thread, but this post of minemight shed some light on the issue. It finds the XPathFactory using a -D parameter that I've never seen documented.
我知道这是一个较旧的线程,但我的这篇文章可能会阐明这个问题。它使用我从未见过的 -D 参数找到 XPathFactory。