Dyllan M
Dyllan M

Reputation: 301

Java External Class Loading ClassDefNotFoundError

So for the mod I'm writing, you have the ability to program your own perks to be used by your character. These perks are compiled and then put into a folder called "perks". I created an Abstract Class that is to be extended by all of these external perks, and it is held in the main jar.

Perk Abstract Class:

public abstract class Perk {

    public abstract void onCall( RCPlayer caller );

}

Example Perk:

public class ExamplePerk extends Perk {

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

}

The method I use for loading in these external Jars. I've stripped out all of the null checks and try/catch statements to keep clean.

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() );
}

Full error: https://gyazo.com/e10acb615d88c50480a57118d54a3b17

It is throwing a ClassNoDefFoundError because it cannot find the "Perk" abstract class.

My question is, how do I specify at runtime where the Perk class is located? At compile time I just add the library, but when it comes time to use the Perk class as an extension, the program flops and throws this error.

If I add the whole main jar to the perks folder, it does work. However this is bad practice as I would have to include all of the project files & it would be a mess.

Upvotes: 0

Views: 41

Answers (2)

gagan singh
gagan singh

Reputation: 1611

Trying explicitly mentioning the parent classloader for perks impls. ClassLoader cl = new URLClassLoader( urls, Perk.class.getClassLoader() );

Most probably Perk.class is not loaded by ThreadContext classloader.

Upvotes: 1

thejavagirl
thejavagirl

Reputation: 66

This isn't working because it's trying to instantiate an abstract class which is not possible.

See this link - you need a reference to the actual subclass.

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

Upvotes: 1

Related Questions