import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class DirectoryLoader extends ClassLoader {
    private final Path directory;

    public DirectoryLoader(Path directory, ClassLoader parent) {
        super(parent);
        this.directory = directory.toAbsolutePath().normalize();
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Path file = directory.resolve(name.replace('.', '/') + ".class").normalize();
        if (!file.startsWith(directory)) {
            throw new ClassNotFoundException(name);
        }
        try {
            byte[] bytecode = Files.readAllBytes(file);
            return defineClass(name, bytecode, 0, bytecode.length);
        } catch (IOException e) {
            throw new ClassNotFoundException(name, e);
        }
    }

    public static void main(String[] args) throws ReflectiveOperationException {
        if (args.length != 1) {
            throw new IllegalArgumentException("Specify the plugin directory");
        }
        ClassLoader loader = new DirectoryLoader(
                Path.of(args[0]), DirectoryLoader.class.getClassLoader());
        Class<?> type = Class.forName("example.plugin.Message", true, loader);
        Object instance = type.getDeclaredConstructor().newInstance();
        System.out.println(type.getMethod("text").invoke(instance));
        System.out.println(type.getClassLoader().getClass().getSimpleName());
    }
}
