例子中的WorldWind应用程序在启动时遇到了AbstractMethodError。

8

我被分配创建一个使用WorldWind API的应用程序,并为了熟悉该API,我尝试运行“HelloWorldWind”示例应用程序。但是当我运行时,会得到以下错误堆栈:

Exception in thread "main" java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
    at gov.nasa.worldwind.util.WWXML.createDocumentBuilder(WWXML.java:61)
    at gov.nasa.worldwind.util.WWXML.openDocumentStream(WWXML.java:236)
    at gov.nasa.worldwind.util.WWXML.openDocumentStream(WWXML.java:223)
    at gov.nasa.worldwind.util.WWXML.openDocumentFile(WWXML.java:175)
    at gov.nasa.worldwind.util.WWXML.openDocument(WWXML.java:148)
    at gov.nasa.worldwind.Configuration.loadConfigDoc(Configuration.java:131)
    at gov.nasa.worldwind.Configuration.<init>(Configuration.java:108)
    at gov.nasa.worldwind.Configuration.<clinit>(Configuration.java:76)
    at gov.nasa.worldwindx.examples.HelloWorldWind.main(HelloWorldWind.java:
WWXML.createDocumentBuilder 的作用如下所述:
public static DocumentBuilder createDocumentBuilder(boolean isNamespaceAware)
{
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
    docBuilderFactory.setNamespaceAware(isNamespaceAware);
    if (Configuration.getJavaVersion() >= 1.6)
    {
        try
        {
            docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
                false);    // Not getting past here
        }
        catch (ParserConfigurationException e)
        {   // Note it and continue on. Some Java5 parsers don't support the feature.
            String message = Logging.getMessage("XML.NonvalidatingNotSupported");
            Logging.logger().finest(message);
        }
    }
    ...
阅读一些在线材料,有人指责 jogl,因为我在64位系统上运行,但是我的构建路径中已经有必要的jar文件。此外,在浏览器中尝试上面显示的URL会返回404页面,这让我认为可能是原因该URL只是一种格式化一些首选项的方法。由于我没有 DocumentBuilderFactory.setFeature 的源代码,所以我无法看到里面出了什么问题。

我的问题实际上与 jogl 有关,还是与其他什么有关?

2个回答

14
这是一种类路径问题。当JVM尝试调用抽象方法(不允许)时,会抛出AbstractMethodError异常。在JavaSE 5中,将一个名为DocumentBuilderFactory.setFeature(String, boolean)的抽象方法添加到了DocumentBuilderFactory中,所以使用J2SE 1.4.2版本编译的实现将没有该方法。当在它们上调用setFeature(String, boolean)时,就会发生此错误。
可能你的类路径上有一个旧的XML库,返回了DocumetnBuilderFactory.newInstance()的实例。问题可能不在于JOGL本身,而是JOGL作为依赖项引入了一个旧的XML库。

我刚刚检查了从DocumentBuilderFactory.newInstance()返回的类类型,它是一个DocumentBuilderFactoryImpl。显然已经实现了setFeature方法,并且根据这里的说法,在其中不应该有任何抛出AbstractMethodError的东西。 - MBraedley
3
你应该检查加载的xerces版本。你可以调用MyClass.class.getClassLoader().getResource("org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class");并打印结果URL来实现这一点。将MyClass.class替换为相关的类,比如HelloWorldWind.class可能适用。希望你能检查由URL指示的jar文件以确定其年代。 - Dev
正在使用的JAR文件是随WorldWind 2.5.0版本一起提供的,因此假定它应该可以工作。我在WorldWind论坛中没有看到任何迹象表明这是问题的原因。 - MBraedley
是的,你走在正确的道路上。虽然最新版本的xerces实现了那个方法,但一些早期版本没有,包括我正在使用的版本。不知道为什么WorldWind在他们的下载中没有使用最新版本。 - MBraedley

1
你需要去 WWXML 课堂并替换以下内容:

docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
                false);

使用:

docBuilderFactory.setNamespaceAware(true);

Java的完整方法如下:
    public static DocumentBuilder createDocumentBuilder(boolean isNamespaceAware)
{
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();

    docBuilderFactory.setNamespaceAware(isNamespaceAware);

    if (Configuration.getJavaVersion() >= 1.6)
    {
        docBuilderFactory.setNamespaceAware(true);
    }

    try
    {
        return docBuilderFactory.newDocumentBuilder();
    }
    catch (ParserConfigurationException e)
    {
        String message = Logging.getMessage("XML.ParserConfigurationException");
        Logging.logger().finest(message);
        throw new WWRuntimeException(e);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接