当前位置: 首页 > 面试题库 >

Saxon-HE 9.3的javax.xml.xpath.XPathFactory提供程序-配置文件中的语法错误

燕英逸
2023-03-14
问题内容

我在Mac OS X和Saxon-HE 9.3.0.5上使用Java SE
6。ServiceLoader无法找到的Saxon实现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)

查找过程第3点中newInstancejavax.xml.xpath.XPathFactory状态方法的javadoc,用于本地化以下实现:

要求类加载器在资源目录META-INF /
services中提供与javax.xml.xpath.XPathFactory匹配的服务提供者配置文件。有关文件格式和解析规则,请参见JAR文件规范。

JAR文件规范的“
服务提供者”部分指出:

该文件应包含一个以换行符分隔的唯一的具体提供程序类名称的列表。

但是,如果我提取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);
    }
}

问题答案:

Michael Kay
在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());


 类似资料:
  • 问题内容: 在以下代码示例中: 我收到类似“未知提供者$ cookieStore”的angularjs错误。 “ myApp”具有Dependenciy和“ ngCookies”,并且对angular-cookies.min.js进行了评分,那么该代码有什么问题? 那是我在.config中执行此操作的事实吗? 问题答案: 因为只能在配置时传递提供程序,所以我最终没有通过请求转换器而是通过将服务创建

  • 问题内容: 有人可以向我解释差异吗? Provisioner-在docker中安装,运行,拉出容器中的一项工作。 提供程序-是运行VM的东西。即VBox运行ubuntu OS映像。 Docker如何成为提供者?它直接运行一些docker镜像吗?如果我在Windows上,必须有一些boot2docker的隐藏用法,对不对?我什么时候使用每个? 问题答案: Docker Provisioner帮助准备

  • 我的问题是,这个“提供商app”是一个什么样的app?是否有任何Android API,该应用程序应该实现,以作为配置提供商?此配套应用程序如何将配置更改挂钩到中,以便托管应用程序能够检索这些更改? 我在这里问这个问题,因为不幸的是,我在Android文档中没有找到任何引用。

  • 问题内容: 我正在使用SQLMemebershipProvider并使用配置文件。我有一个名为UserProfile的自定义类,该类继承自ProfileBase类,并使用它来设置自定义属性,例如“FullName”。我想遍历数据库中的所有用户并获得对其配置文件属性的访问。在每次迭代中,我都调用ProfileBase.Create()以获得新的配置文件,然后访问属性。 在我看来,每次调用Profil

  • 我有一个关于android文件提供商的问题。我想保存一个pdf文档并用默认程序打开它。我不想将其保存在外部存储器中。 在我成功地将pdf保存到filedirectory/export/temp之后。pdf, 我尝试使用FileProvider生成URI。getUriForFile()。 问题:我必须传递什么作为第二个参数“Authority”-我的文件的位置、可以授予URI权限的类或其他什么?无论

  • 我正在尝试为drools会话配置JPA持久性(代码来自drools文档) > 我在pom.xml中添加了drools-persistence-jpa、Bitronix事务管理器和com.h2database依赖项 我在“src/META-INF”中的Eclipse项目中创建了一个META-INF文件夹作为Source-Folder。 [...]EntityManagerFactory emf=pe