我有一个从包类扩展的类,当程序运行时,该包类可能会或可能不会在类路径中,除非满足依赖关系,否则不会调用它,但是它似乎惹恼了在尝试时抛出 NoClassDefFoundError 的 java 验证程序加载程序,
有什么办法吗?
我有一个从包类扩展的类,当程序运行时,该包类可能会或可能不会在类路径中,除非满足依赖关系,否则不会调用它,但是它似乎惹恼了在尝试时抛出 NoClassDefFoundError 的 java 验证程序加载程序,
有什么办法吗?
有什么办法吗?
在实践中,没有。超类必须在类路径中可用,才能成功加载、链接和验证子类。这必须在类被初始化并创建它的实例之前发生。
如果您不能确定超类是否可用,则需要删除对子类的所有直接和间接静态依赖,然后使用Class.forName()
. 如果超类“丢失”,这将失败,但您将得到一个不同的异常(不是Error
),并且如果您的应用程序旨在处理丢失的类,则它有可能继续。
诸如 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.
}
}
}
作为解决此问题的方法,如果您的类(子类)在类路径中可用,则可以通过使用 方法将类文件作为资源加载来检查父类在类路径中是否可用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");
}
}
}