Bukkit-API  1.7.9-R0.2
The inofficial Bukkit-API
PluginClassLoader.java
1 package org.bukkit.plugin.java;
2 
3 import java.io.File;
4 import java.net.MalformedURLException;
5 import java.net.URL;
6 import java.net.URLClassLoader;
7 import java.util.HashMap;
8 import java.util.Map;
9 import java.util.Set;
10 
11 import org.apache.commons.lang.Validate;
14 
15 /**
16  * A ClassLoader for plugins, to allow shared classes across multiple plugins
17  */
18 final class PluginClassLoader extends URLClassLoader {
19  private final JavaPluginLoader loader;
20  private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
21  private final PluginDescriptionFile description;
22  private final File dataFolder;
23  private final File file;
24  final JavaPlugin plugin;
25  private JavaPlugin pluginInit;
26  private IllegalStateException pluginState;
27 
28  PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws InvalidPluginException, MalformedURLException {
29  super(new URL[] {file.toURI().toURL()}, parent);
30  Validate.notNull(loader, "Loader cannot be null");
31 
32  this.loader = loader;
33  this.description = description;
34  this.dataFolder = dataFolder;
35  this.file = file;
36 
37  try {
38  Class<?> jarClass;
39  try {
40  jarClass = Class.forName(description.getMain(), true, this);
41  } catch (ClassNotFoundException ex) {
42  throw new InvalidPluginException("Cannot find main class `" + description.getMain() + "'", ex);
43  }
44 
45  Class<? extends JavaPlugin> pluginClass;
46  try {
47  pluginClass = jarClass.asSubclass(JavaPlugin.class);
48  } catch (ClassCastException ex) {
49  throw new InvalidPluginException("main class `" + description.getMain() + "' does not extend JavaPlugin", ex);
50  }
51 
52  plugin = pluginClass.newInstance();
53  } catch (IllegalAccessException ex) {
54  throw new InvalidPluginException("No public constructor", ex);
55  } catch (InstantiationException ex) {
56  throw new InvalidPluginException("Abnormal plugin type", ex);
57  }
58  }
59 
60  @Override
61  protected Class<?> findClass(String name) throws ClassNotFoundException {
62  return findClass(name, true);
63  }
64 
65  Class<?> findClass(String name, boolean checkGlobal) throws ClassNotFoundException {
66  if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) {
67  throw new ClassNotFoundException(name);
68  }
69  Class<?> result = classes.get(name);
70 
71  if (result == null) {
72  if (checkGlobal) {
73  result = loader.getClassByName(name);
74  }
75 
76  if (result == null) {
77  result = super.findClass(name);
78 
79  if (result != null) {
80  loader.setClass(name, result);
81  }
82  }
83 
84  classes.put(name, result);
85  }
86 
87  return result;
88  }
89 
90  Set<String> getClasses() {
91  return classes.keySet();
92  }
93 
94  synchronized void initialize(JavaPlugin javaPlugin) {
95  Validate.notNull(javaPlugin, "Initializing plugin cannot be null");
96  Validate.isTrue(javaPlugin.getClass().getClassLoader() == this, "Cannot initialize plugin outside of this class loader");
97  if (this.plugin != null || this.pluginInit != null) {
98  throw new IllegalArgumentException("Plugin already initialized!", pluginState);
99  }
100 
101  pluginState = new IllegalStateException("Initial initialization");
102  this.pluginInit = javaPlugin;
103 
104  javaPlugin.init(loader, loader.server, description, dataFolder, file, this);
105  }
106 }