Java外部类加载ClassDefNotFoundError

时间:2018-05-29 21:28:04

标签: java jar external compile-time

因此,对于我正在编写的mod,您可以编写自己的特权以供角色使用。编译这些权限,然后将其放入名为“perks”的文件夹中。我创建了一个抽象类,它将被所有这些外部特权扩展,并保存在主jar中。

Perk抽象类:

public abstract class Perk {

    public abstract void onCall( RCPlayer caller );

}

示例Perk:

public class ExamplePerk extends Perk {

    public void onCall( RCPlayer ) {
        // do something...
    }

}

我用于在这些外部Jars中加载的方法。 我已经删除了所有的空检查和try / catch语句以保持清洁。

private static LoadStatus loadPerk( String path ) {
    URL url = new File( path ).toURI().toURL();

    URL[] urls = new URL[]{ url };
    YamlConfiguration perkYML = null;

    ClassLoader cl = new URLClassLoader( urls );
    Class<?> cls = Class.forName( main /* class path */, true, cl );
    clazz = cls.asSubclass( Perk.class );

    // Instantiate class & put into a data structure
    perks.put( new Descriptor( main, name, id, description ), clazz.newInstance() );
}

完整错误:https://gyazo.com/e10acb615d88c50480a57118d54a3b17

它抛出一个ClassNoDefFoundError,因为它无法找到“Perk”抽象类。

我的问题是,如何在运行时指定Perk类所在的位置?在编译时我只是添加库,但是当需要使用Perk类作为扩展时,程序会触发并抛出此错误。

如果我将整个主jar添加到perks文件夹,它确实有效。然而,这是不好的做法,因为我必须包括所有的项目文件和这将是一团糟。

2 个答案:

答案 0 :(得分:1)

这不起作用,因为它试图实例化一个不可能的抽象类。

请参阅此链接 - 您需要对实际子类的引用。

https://www.tutorialspoint.com/java/lang/class_assubclass.htm

答案 1 :(得分:1)

尝试明确提到perks impls的父类加载器。 ClassLoader cl = new URLClassLoader(urls,Perk.class.getClassLoader());

很可能Perk.class没有被ThreadContext类加载器加载。