java.lang.NoClassDefFoundError:如何避免加载不存在的类?

时间:2018-07-25 14:48:21

标签: java classloader noclassdeffounderror jit

我们使用一些可选的库。该库仅在可用时访问。但是,JIT在具有可选访问权限的类的构造函数中已经产生了NoClassDefFoundError。

public Configuration {
    public boolean libraryAvailable() {
        return false; // some configuration that signal that the library is not available
    }
}


public class Foo {

   public Foo() {
       ... do some things
   }
   public void callLater() {
       ...
       if( libraryAvailable() ) {
           xyz();
       }
       ...
   }
   private void xyz() {
       new OptionalClass(); // available at compile time but not at runtime
   }
}

如何防止JIT在调用构造函数之前加载调用的所有可能依赖项?

java.lang.NoClassDefFoundError: com/inet/OptionalClass
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
    at java.lang.Class.getConstructor0(Class.java:3075)
    at java.lang.Class.newInstance(Class.java:412)
    ...
 Caused by: java.lang.ClassNotFoundException: com.inet.OptionalClass
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at com.inet.plugin.DependencyClassLoader.loadClass(DependencyClassLoader.java:104)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.inet.plugin.DependencyClassLoader.loadClass(DependencyClassLoader.java:138)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 9 more

3 个答案:

答案 0 :(得分:0)

您可以编写自己的自定义方法,如下面的代码所示,以检查类路径中是否有可用的类。

boolean result=false;
try {
 Class.forName( "your.test.class" );
result=true;
} catch( ClassNotFoundException e ) {
 //Class or Library is not available
}
return result;

答案 1 :(得分:0)

使用Class.forName代替导入您的可选类

StackView

答案 2 :(得分:0)

仅当构造函数为空时,将未使用的代码的类加载与单独的方法解耦。如果有构造函数,则需要将未使用的代码移到单独的类中。这也可以是匿名类。

例如:

new Object () { { 
    new OptionalClass();
} };