1

请注意:虽然有几个关于 SO 的问题粘贴在类似的异常和堆栈跟踪中,但这个问题绝对不是其中任何一个问题,因为我试图了解我的类加载出错的地方。

你好,这里是 Java 8/Groovy 2.4.3/Eclipse Luna。我正在使用BigIP iControl Java 客户端(用于以编程方式控制功能强大的负载平衡器),它又使用 Apache Axis 1.4。在使用 Axis 1.4 时,我得到了以下堆栈跟踪(来自 Eclipse 控制台):

Caught: javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
    at org.apache.axis.utils.XMLUtils.getDOMFactory(XMLUtils.java:221)
    at org.apache.axis.utils.XMLUtils.<clinit>(XMLUtils.java:83)
    at org.apache.axis.configuration.FileProvider.configureEngine(FileProvider.java:179)
    at org.apache.axis.AxisEngine.init(AxisEngine.java:172)
    at org.apache.axis.AxisEngine.<init>(AxisEngine.java:156)
    at org.apache.axis.client.AxisClient.<init>(AxisClient.java:52)
    at org.apache.axis.client.Service.getAxisClient(Service.java:104)
    at org.apache.axis.client.Service.<init>(Service.java:113)
    at iControl.LocalLBPoolLocator.<init>(LocalLBPoolLocator.java:21)
    at iControl.Interfaces.getLocalLBPool(Interfaces.java:351)
    at com.me.myapp.F5Client.run(F5Client.groovy:27)

嗯,让我们看看那个XMLUtils.getDOMFactory方法:

private static DocumentBuilderFactory getDOMFactory() {
    DocumentBuilderFactory dbf;
    try {
        dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
    }
    catch( Exception e ) {
        log.error(Messages.getMessage("exception00"), e );
        dbf = null;
    }
    return( dbf );
}

好的,LN 221 就是那个调用,DocumentBuilderFactory.newInstance()所以让我们来看看它:

public static DocumentBuilderFactory newInstance() {
    return FactoryFinder.find(
        /* The default property name according to the JAXP spec */
        DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
        /* The fallback implementation class name */
        "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
}

剧情变厚了!现在让我们最后看一下FactoryFinder.find

static <T> T find(Class<T> type, String fallbackClassName)
        throws FactoryConfigurationError
{
    final String factoryId = type.getName();
    dPrint("find factoryId =" + factoryId);

    // lots of nasty cruft omitted for brevity...


    // Try Jar Service Provider Mechanism
    T provider = findServiceProvider(type);
    if (provider != null) {
        return provider;
    }
    if (fallbackClassName == null) {
        throw new FactoryConfigurationError(
            "Provider for " + factoryId + " cannot be found");      // <<-- Ahh, here we go
    }

    dPrint("loaded from fallback value: " + fallbackClassName);
    return newInstance(type, fallbackClassName, null, true);
}

因此,如果我正确解释这一点,它就会抛出,FactoryConfigurationError因为它找不到主要的“提供程序类”(无论这意味着什么)并且没有指定回退。但是不是吗?!!对FactoryFinder.find包含非空"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"字符串参数的调用。这让我怀疑我的类路径确实有问题,并且我的代码中某处有一个流氓DocumentBuilderFactory不是在 中定义的rt.jar/javax/xml/parsers那个)正在将 NULL arg 传递给这个 finder 方法。

但这也没有任何意义,因为 Axis 1.4 似乎(至少根据 Maven 存储库)没有任何依赖关系......这意味着唯一的“提供者”javax.xml.*将是rt.jar. 除非,也许,Eclipse 以某种方式搞砸了?我很困惑,请帮助:-/


更新

这绝对是一个 Eclipse 问题。如果我将我的应用程序打包为可执行 JAR 并从命令行运行它,我不会收到此异常。

4

0 回答 0