All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bukkit.plugin.java.PluginClassLoader Maven / Gradle / Ivy

There is a newer version: 2.4.0
Show newest version
package org.bukkit.plugin.java;

import kotlin.jvm.internal.Reflection;
import kotlin.reflect.KClass;
import org.apache.commons.lang.Validate;
import org.bukkit.plugin.InvalidPluginException;
import org.bukkit.plugin.PluginDescriptionFile;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.Set;

/**
 * A ClassLoader for plugins, to allow shared classes across multiple plugins
 */
final class PluginClassLoader extends URLClassLoader {
  // Spigot Start
  static {
    try {
      java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable");
      if (method != null) {
        boolean oldAccessible = method.isAccessible();
        method.setAccessible(true);
        method.invoke(null);
        method.setAccessible(oldAccessible);
      }
    } catch (NoSuchMethodException ex) {
      // Ignore
    } catch (Exception ex) {
      org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Error setting PluginClassLoader as parallel capable", ex);
    }
  }

  final JavaPlugin plugin;
  private final JavaPluginLoader loader;
  private final Map> classes = new java.util.concurrent.ConcurrentHashMap>(); // Spigot
  private final PluginDescriptionFile description;
  private final File dataFolder;
  private final File file;
  private JavaPlugin pluginInit;
  private IllegalStateException pluginState;
  // Spigot End

  PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws InvalidPluginException, MalformedURLException {
    super(new URL[]{file.toURI().toURL()}, parent);
    Validate.notNull(loader, "Loader cannot be null");

    this.loader = loader;
    this.description = description;
    this.dataFolder = dataFolder;
    this.file = file;

    try {
      Class jarClass;
      try {
        jarClass = Class.forName(description.getMain(), true, this);
      } catch (ClassNotFoundException ex) {
        throw new InvalidPluginException("Cannot find main class `" + description.getMain() + "'", ex);
      }

      Class pluginClass;
      try {
        pluginClass = jarClass.asSubclass(JavaPlugin.class);
      } catch (ClassCastException ex) {
        throw new InvalidPluginException("main class `" + description.getMain() + "' does not extend JavaPlugin", ex);
      }

      // ChestMC start - allows main classes to be kotlin object.
      KClass clazz = Reflection.getOrCreateKotlinClass(pluginClass);
      plugin = clazz.getObjectInstance() != null ? clazz.getObjectInstance() : pluginClass.newInstance();
      // ChestMC end.

    } catch (IllegalAccessException ex) {
      throw new InvalidPluginException("No public constructor", ex);
    } catch (InstantiationException ex) {
      throw new InvalidPluginException("Abnormal plugin type", ex);
    }
  }

  @Override
  protected Class findClass(String name) throws ClassNotFoundException {
    return findClass(name, true);
  }

  Class findClass(String name, boolean checkGlobal) throws ClassNotFoundException {
    if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) {
      throw new ClassNotFoundException(name);
    }
    Class result = classes.get(name);

    if (result == null) {
      if (checkGlobal) {
        result = loader.getClassByName(name);
      }

      if (result == null) {
        result = super.findClass(name);

        if (result != null) {
          loader.setClass(name, result);
        }
      }

      classes.put(name, result);
    }

    return result;
  }

  Set getClasses() {
    return classes.keySet();
  }

  synchronized void initialize(JavaPlugin javaPlugin) {
    Validate.notNull(javaPlugin, "Initializing plugin cannot be null");
    Validate.isTrue(javaPlugin.getClass().getClassLoader() == this, "Cannot initialize plugin outside of this class loader");
    if (this.plugin != null || this.pluginInit != null) {
      throw new IllegalArgumentException("Plugin already initialized!", pluginState);
    }

    pluginState = new IllegalStateException("Initial initialization");
    this.pluginInit = javaPlugin;

    javaPlugin.init(loader, loader.server, description, dataFolder, file, this);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy