-2

I wrote my classloader:

package ru.sberbank.school.homework8;

import ru.sberbank.school.homework8.plugin.Plugin;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class PluginManager extends ClassLoader {
private final String pluginRootDirectory;

public PluginManager(String pluginRootDirectory) {
    this.pluginRootDirectory = pluginRootDirectory;
}

public Plugin load(String pluginName, String pluginClassName) {
    String name = pluginName + "." + pluginClassName;
    try {
        Class clazz;
        try {
            clazz = super.findSystemClass(name);
        } catch (ClassNotFoundException e) {
            String fileName = pluginRootDirectory + "\\" + pluginName + "\\" + pluginClassName + ".class";
            try (FileInputStream fin = new FileInputStream(fileName)) {
                byte[] buffer = new byte[(int) (new File(fileName).length())];
                fin.read(buffer);
                clazz = defineClass(name, buffer, 0, buffer.length);
            }
        }
        return (Plugin)clazz.newInstance();

    } catch (IOException | InstantiationException | IllegalAccessException ignored) {
        return null;
    }
}

}

When I run it:

package ru.sberbank.school.homework8;

import ru.sberbank.school.homework8.plugin.Plugin;

public class PluginManagerTest {
    public static void main(String[] args) {
        String pluginRootDirectory = "D:\\sbt\\target\\classes\\ru\\sberbank\\school\\homework8";
        PluginManager pluginManager = new PluginManager(pluginRootDirectory);
        Plugin plugin = pluginManager.load("plugin", "PluginImpl");
        if (plugin != null) {
            plugin.doUseful();
        }
    }
}

Exception in thread "main" java.lang.NoClassDefFoundError: plugin/PluginImpl (wrong name: ru/sberbank/school/homework8/plugin/PluginImpl) at java.lang.ClassLoader.defineClass1(Native Method)

I get NoClassDefFoundError. Why??? How can I fix it???

Help me, please!

package ru.sberbank.school.homework8.plugin;

public class PluginImpl implements Plugin {
    @Override
    public void doUseful() {
        System.out.println("My plugin!");
    }
}
Iakov Burtsev
  • 377
  • 1
  • 2
  • 15

1 Answers1

0

You get this error because you don't provide the correct FQN of your class, indeed in your load method, you try to find the class corresponding to pluginName + "." + pluginClassName that will be in your case plugin.PluginImpl but the package name of your class PluginImpl is actually ru.sberbank.school.homework8.plugin such that the real FQN of your class is ru.sberbank.school.homework8.plugin.PluginImpl.

To fix this problem, you need to replace:

Plugin plugin = pluginManager.load("plugin", "PluginImpl");

With:

Plugin plugin = pluginManager.load("ru.sberbank.school.homework8.plugin", "PluginImpl");

Or you could modify your method load to add a prefix assuming that you will always retrieve your plugins from the same root package:

public Plugin load(String pluginName, String pluginClassName) {
    String name = "ru.sberbank.school.homework8." + pluginName + "." + pluginClassName;
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122