2

我有一个从包类扩展的类,当程序运行时,该包类可能会或可能不会在类路径中,除非满足依赖关系,否则不会调用它,但是它似乎惹恼了在尝试时抛出 NoClassDefFoundError 的 java 验证程序加载程序,

有什么办法吗?

4

3 回答 3

2

有什么办法吗?

在实践中,没有。超类必须在类路径中可用,才能成功加载、链接和验证子类。这必须在类被初始化并创建它的实例之前发生。


如果您不能确定超类是否可用,则需要删除对子类的所有直接和间接静态依赖,然后使用Class.forName(). 如果超类“丢失”,这将失败,但您将得到一个不同的异常(不是Error),并且如果您的应用程序旨在处理丢失的类,则它有可能继续。

于 2013-08-04T01:56:44.283 回答
0

诸如 Spring 之类的具有“可选使用”代码的框架取决于其他库,使用“策略模式”将特定于依赖项的代码放入“内部类”或单独的类中。

外部类可以加​​载并运行良好;只有当您尝试实例化内部类时,才会抛出 NoClassDefFoundError。

所以外部类通常会尝试(try-catch)实例化一个要使用的策略,然后如果失败则实例化一个回退策略。

public class MyService {
    protected MyStrategy strategy;

    // constructor;
    //    -- choose our strategy.
    public MyService() {
        try {
            this.strategy = new ExternalLib_Strategy();
        } catch (NoClassDefFoundError x) {
            // external library not available.
            this.strategy = new Standard_Strategy ();
        }
    }

    // --------------------------------------------------------

    protected interface MyStrategy {
        public void doSomething();
    }

    protected static class ExternalLib_Strategy implements MyStrategy {
        ExternalLib lib = org.thirdparty.ExternalLib.getInstance();   // linkage may
        public void doSomething() {
            // ... use the library for additional functionality.
        }
    }

    protected static class Standard_Strategy {
        public void doSomething() {
            // ... basic/ fallback functionality.
        }
    }

}
于 2013-08-04T00:40:33.533 回答
0

作为解决此问题的方法,如果您的类(子类)在类路径中可用,则可以通过使用 方法将类文件作为资源加载来检查父类在类路径中是否可用ClassLoader.getResource()。此方法永远不会抛出未找到类的异常。但是,如果找不到该类,这将返回 null。如果资源为空,您可以避免使用您的类。

请参阅下面的示例代码:

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
    Object instance = Test.class.getClassLoader().getResource("com/test/package/Base.class");
    Derived derived = null;
    if(instance !=null) {
        derived = new Derived();
        System.out.println(derived.getString()); // call the getString method in base class
    }
    else {
        // The class is not available. But no Exception
                 System.out.println("No Hope"); 

    }

}

}

于 2013-08-04T01:22:25.260 回答