2

I wrote my own classloader, which works with classes, which implements interface Plugin. But I can't cast Class to Plugin. What's wrong?

public Plugin load(String pluginName, String pluginClassName) {
        SimpleClassLoader system = new SimpleClassLoader();
        system.setClassName(pluginClassName);
        Plugin aClass = null;
        try {
            aClass = (Plugin) system.loadClass(pluginRootDirectory + pluginName + "\\" + pluginClassName + ".class");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return aClass;
    }

Error:(18, 47) java: incompatible types: java.lang.Class cannot be converted to Plugin

I addition this is the main part of my SimpleClassLoader class which extends ClassLoader.

@Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] bytes;
        try {
            bytes = Files.readAllBytes(new File(name).toPath());
        } catch (IOException e) {
            throw new ClassNotFoundException();
        }
        return  defineClass(className, bytes, 0, bytes.length);
    }
jenius
  • 257
  • 1
  • 4
  • 17

4 Answers4

3

Because

classloader.loadClass("myclass.class");

Is going to return you Class type object and not custom Plugin type. http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#loadClass%28java.lang.String%29

SMA
  • 36,381
  • 8
  • 49
  • 73
1

You need to create a new instance of the class. Don't name your Plugin aClass since that's not what it is.

Class clazz = system.loadClass(
                   pluginRootDirectory + 
                   pluginName + "\\" + 
                   pluginClassName + ".class");

Plugin plugin = (Plugin) clazz.newInstance();

This creates the plugin using reflection. SimpleClassLoader only turned a string into a class. It doesn't give you the object you want to cast to a plugin.

See also Using reflection in Java to create a new instance with the reference variable type set to the new instance class name? and if the plugin has an argument constructor see Can I use Class.newInstance() with constructor arguments?

Community
  • 1
  • 1
candied_orange
  • 7,036
  • 2
  • 28
  • 62
0

With this

public Plugin load(String pluginName, String pluginClassName) {}

you will return object of type Plugin, to return type what extends Plugin you need to write

public Class<? extends Plugin> load(String pluginName, String pluginClassName) {}
0

I found the solution, the main problem was that the same classloader loaded my class and interface which is implemented, as a result I can't cast. And we need to load Plugin Interface with other classloader.

jenius
  • 257
  • 1
  • 4
  • 17