summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/bukkit/plugin/PluginDescriptionFile.java4
-rw-r--r--src/main/java/org/bukkit/plugin/java/JavaPlugin.java120
-rw-r--r--src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java173
-rw-r--r--src/main/java/org/bukkit/plugin/java/PluginClassLoader.java116
4 files changed, 165 insertions, 248 deletions
diff --git a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
index d2a59e40..1d79e637 100644
--- a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
+++ b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
@@ -773,6 +773,10 @@ public final class PluginDescriptionFile {
return name + " v" + version;
}
+ /**
+ * @deprecated unused
+ */
+ @Deprecated
public String getClassLoaderOf() {
return classLoaderOf;
}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
index 3815da22..bdecbea2 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
@@ -13,12 +13,14 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Server;
+import org.bukkit.Warning.WarningState;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.plugin.AuthorNagException;
import org.bukkit.plugin.PluginBase;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
@@ -36,7 +38,6 @@ import com.avaje.ebeaninternal.server.ddl.DdlGenerator;
*/
public abstract class JavaPlugin extends PluginBase {
private boolean isEnabled = false;
- private boolean initialized = false;
private PluginLoader loader = null;
private Server server = null;
private File file = null;
@@ -49,7 +50,37 @@ public abstract class JavaPlugin extends PluginBase {
private File configFile = null;
private PluginLogger logger = null;
- public JavaPlugin() {}
+ public JavaPlugin() {
+ final ClassLoader classLoader = this.getClass().getClassLoader();
+ if (!(classLoader instanceof PluginClassLoader)) {
+ throw new IllegalStateException("JavaPlugin requires " + PluginClassLoader.class.getName());
+ }
+ ((PluginClassLoader) classLoader).initialize(this);
+ }
+
+ /**
+ * @deprecated This method is intended for unit testing purposes when the
+ * other {@linkplain #JavaPlugin(JavaPluginLoader,
+ * PluginDescriptionFile, File, File) constructor} cannot be used.
+ * <p>
+ * Its existence may be temporary.
+ */
+ @Deprecated
+ protected JavaPlugin(final PluginLoader loader, final Server server, final PluginDescriptionFile description, final File dataFolder, final File file) {
+ final ClassLoader classLoader = this.getClass().getClassLoader();
+ if (classLoader instanceof PluginClassLoader) {
+ throw new IllegalStateException("Cannot use initialization constructor at runtime");
+ }
+ init(loader, server, description, dataFolder, file, classLoader);
+ }
+
+ protected JavaPlugin(final JavaPluginLoader loader, final PluginDescriptionFile description, final File dataFolder, final File file) {
+ final ClassLoader classLoader = this.getClass().getClassLoader();
+ if (classLoader instanceof PluginClassLoader) {
+ throw new IllegalStateException("Cannot use initialization constructor at runtime");
+ }
+ init(loader, loader.server, description, dataFolder, file, classLoader);
+ }
/**
* Returns the folder that the plugin data's files are located in. The
@@ -223,50 +254,46 @@ public abstract class JavaPlugin extends PluginBase {
}
/**
- * Initializes this plugin with the given variables.
- * <p>
- * This method should never be called manually.
- *
- * @param loader PluginLoader that is responsible for this plugin
- * @param server Server instance that is running this plugin
- * @param description PluginDescriptionFile containing metadata on this
- * plugin
- * @param dataFolder Folder containing the plugin's data
- * @param file File containing this plugin
- * @param classLoader ClassLoader which holds this plugin
+ * @deprecated This method is legacy and will be removed - it must be
+ * replaced by the specially provided constructor(s).
*/
+ @Deprecated
protected final void initialize(PluginLoader loader, Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader) {
- if (!initialized) {
- this.initialized = true;
- this.loader = loader;
- this.server = server;
- this.file = file;
- this.description = description;
- this.dataFolder = dataFolder;
- this.classLoader = classLoader;
- this.configFile = new File(dataFolder, "config.yml");
- this.logger = new PluginLogger(this);
-
- if (description.isDatabaseEnabled()) {
- ServerConfig db = new ServerConfig();
-
- db.setDefaultServer(false);
- db.setRegister(false);
- db.setClasses(getDatabaseClasses());
- db.setName(description.getName());
- server.configureDbConfig(db);
-
- DataSourceConfig ds = db.getDataSourceConfig();
-
- ds.setUrl(replaceDatabaseString(ds.getUrl()));
- dataFolder.mkdirs();
-
- ClassLoader previous = Thread.currentThread().getContextClassLoader();
-
- Thread.currentThread().setContextClassLoader(classLoader);
- ebean = EbeanServerFactory.create(db);
- Thread.currentThread().setContextClassLoader(previous);
- }
+ if (server.getWarningState() == WarningState.OFF) {
+ return;
+ }
+ getLogger().log(Level.WARNING, getClass().getName() + " is already initialized", server.getWarningState() == WarningState.DEFAULT ? null : new AuthorNagException("Explicit initialization"));
+ }
+
+ final void init(PluginLoader loader, Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader) {
+ this.loader = loader;
+ this.server = server;
+ this.file = file;
+ this.description = description;
+ this.dataFolder = dataFolder;
+ this.classLoader = classLoader;
+ this.configFile = new File(dataFolder, "config.yml");
+ this.logger = new PluginLogger(this);
+
+ if (description.isDatabaseEnabled()) {
+ ServerConfig db = new ServerConfig();
+
+ db.setDefaultServer(false);
+ db.setRegister(false);
+ db.setClasses(getDatabaseClasses());
+ db.setName(description.getName());
+ server.configureDbConfig(db);
+
+ DataSourceConfig ds = db.getDataSourceConfig();
+
+ ds.setUrl(replaceDatabaseString(ds.getUrl()));
+ dataFolder.mkdirs();
+
+ ClassLoader previous = Thread.currentThread().getContextClassLoader();
+
+ Thread.currentThread().setContextClassLoader(classLoader);
+ ebean = EbeanServerFactory.create(db);
+ Thread.currentThread().setContextClassLoader(previous);
}
}
@@ -289,9 +316,12 @@ public abstract class JavaPlugin extends PluginBase {
* Gets the initialization status of this plugin
*
* @return true if this plugin is initialized, otherwise false
+ * @deprecated This method cannot return false, as {@link
+ * JavaPlugin} is now initialized in the constructor.
*/
+ @Deprecated
public final boolean isInitialized() {
- return initialized;
+ return true;
}
/**
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index ea30d83d..57681dc4 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -4,10 +4,8 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -49,44 +47,19 @@ import com.google.common.collect.ImmutableList;
/**
* Represents a Java plugin loader, allowing plugins in the form of .jar
*/
-public class JavaPluginLoader implements PluginLoader {
+public final class JavaPluginLoader implements PluginLoader {
final Server server;
- final boolean extended = this.getClass() != JavaPluginLoader.class;
- boolean warn;
+ private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
+ private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
+ private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<String, PluginClassLoader>();
- private final Pattern[] fileFilters0 = new Pattern[] { Pattern.compile("\\.jar$"), };
/**
- * @deprecated Internal field that wasn't intended to be exposed
- */
- @Deprecated
- protected final Pattern[] fileFilters = fileFilters0;
-
- private final Map<String, Class<?>> classes0 = new HashMap<String, Class<?>>();
- /**
- * @deprecated Internal field that wasn't intended to be exposed
- */
- @Deprecated
- protected final Map<String, Class<?>> classes = classes0;
-
- private final Map<String, PluginClassLoader> loaders0 = new LinkedHashMap<String, PluginClassLoader>();
- /**
- * @deprecated Internal field that wasn't intended to be exposed
- */
- @Deprecated
- protected final Map<String, PluginClassLoader> loaders = loaders0;
-
- /**
- * This class was not meant to be extended
+ * This class was not meant to be constructed explicitly
*/
@Deprecated
public JavaPluginLoader(Server instance) {
Validate.notNull(instance, "Server cannot be null");
server = instance;
- warn = instance.getWarningState() != WarningState.OFF;
- if (extended && warn) {
- warn = false;
- instance.getLogger().log(Level.WARNING, "JavaPluginLoader not intended to be extended by " + getClass() + ", and may be final in a future version of Bukkit");
- }
}
public Plugin loadPlugin(File file) throws InvalidPluginException {
@@ -104,7 +77,7 @@ public class JavaPluginLoader implements PluginLoader {
}
File dataFolder = new File(file.getParentFile(), description.getName());
- File oldDataFolder = extended ? getDataFolder(file) : getDataFolder0(file); // Don't warn on deprecation, but maintain overridability
+ File oldDataFolder = getDataFolder(file);
// Found old data folder
if (dataFolder.equals(oldDataFolder)) {
@@ -145,75 +118,31 @@ public class JavaPluginLoader implements PluginLoader {
}
for (String pluginName : depend) {
- if (loaders0 == null) {
+ if (loaders == null) {
throw new UnknownDependencyException(pluginName);
}
- PluginClassLoader current = loaders0.get(pluginName);
+ PluginClassLoader current = loaders.get(pluginName);
if (current == null) {
throw new UnknownDependencyException(pluginName);
}
}
- PluginClassLoader loader = null;
- JavaPlugin result = null;
-
+ PluginClassLoader loader;
try {
- URL[] urls = new URL[1];
-
- urls[0] = file.toURI().toURL();
-
- if (description.getClassLoaderOf() != null) {
- loader = loaders0.get(description.getClassLoaderOf());
- loader.addURL(urls[0]);
- } else {
- loader = new PluginClassLoader(this, urls, getClass().getClassLoader(), null);
- }
-
- Class<?> jarClass = Class.forName(description.getMain(), true, loader);
- Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
-
- Constructor<? extends JavaPlugin> constructor = plugin.getConstructor();
-
- result = constructor.newInstance();
-
- result.initialize(this, server, description, dataFolder, file, loader);
- } catch (InvocationTargetException ex) {
- throw new InvalidPluginException(ex.getCause());
+ loader = new PluginClassLoader(this, getClass().getClassLoader(), description, dataFolder, file);
+ } catch (InvalidPluginException ex) {
+ throw ex;
} catch (Throwable ex) {
throw new InvalidPluginException(ex);
}
- loaders0.put(description.getName(), loader);
+ loaders.put(description.getName(), loader);
- return result;
+ return loader.plugin;
}
- /**
- * @deprecated Relic method from PluginLoader that didn't get purged
- */
- @Deprecated
- public Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException {
- if (warn) {
- server.getLogger().log(Level.WARNING, "Method \"public Plugin loadPlugin(File, boolean)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- warn = false;
- }
- return loadPlugin(file);
- }
-
- /**
- * @deprecated Internal method that wasn't intended to be exposed
- */
- @Deprecated
- protected File getDataFolder(File file) {
- if (warn) {
- server.getLogger().log(Level.WARNING, "Method \"protected File getDataFolder(File)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- warn = false;
- }
- return getDataFolder0(file);
- }
-
- private File getDataFolder0(File file) {
+ private File getDataFolder(File file) {
File dataFolder = null;
String filename = file.getName();
@@ -272,32 +201,20 @@ public class JavaPluginLoader implements PluginLoader {
}
public Pattern[] getPluginFileFilters() {
- return fileFilters0.clone();
- }
-
- /**
- * @deprecated Internal method that wasn't intended to be exposed
- */
- @Deprecated
- public Class<?> getClassByName(final String name) {
- if (warn) {
- server.getLogger().log(Level.WARNING, "Method \"public Class<?> getClassByName(String)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- warn = false;
- }
- return getClassByName0(name);
+ return fileFilters.clone();
}
- Class<?> getClassByName0(final String name) {
- Class<?> cachedClass = classes0.get(name);
+ Class<?> getClassByName(final String name) {
+ Class<?> cachedClass = classes.get(name);
if (cachedClass != null) {
return cachedClass;
} else {
- for (String current : loaders0.keySet()) {
- PluginClassLoader loader = loaders0.get(current);
+ for (String current : loaders.keySet()) {
+ PluginClassLoader loader = loaders.get(current);
try {
- cachedClass = loader.extended ? loader.findClass(name, false) : loader.findClass0(name, false); // Don't warn on deprecation, but maintain overridability
+ cachedClass = loader.findClass(name, false);
} catch (ClassNotFoundException cnfe) {}
if (cachedClass != null) {
return cachedClass;
@@ -307,21 +224,9 @@ public class JavaPluginLoader implements PluginLoader {
return null;
}
- /**
- * @deprecated Internal method that wasn't intended to be exposed
- */
- @Deprecated
- public void setClass(final String name, final Class<?> clazz) {
- if (warn) {
- server.getLogger().log(Level.WARNING, "Method \"public void setClass(String, Class<?>)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- warn = false;
- }
- setClass0(name, clazz);
- }
-
- void setClass0(final String name, final Class<?> clazz) {
- if (!classes0.containsKey(name)) {
- classes0.put(name, clazz);
+ void setClass(final String name, final Class<?> clazz) {
+ if (!classes.containsKey(name)) {
+ classes.put(name, clazz);
if (ConfigurationSerializable.class.isAssignableFrom(clazz)) {
Class<? extends ConfigurationSerializable> serializable = clazz.asSubclass(ConfigurationSerializable.class);
@@ -330,20 +235,8 @@ public class JavaPluginLoader implements PluginLoader {
}
}
- /**
- * @deprecated Internal method that wasn't intended to be exposed
- */
- @Deprecated
- public void removeClass(String name) {
- if (warn) {
- server.getLogger().log(Level.WARNING, "Method \"public void removeClass(String)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- warn = false;
- }
- removeClass0(name);
- }
-
- private void removeClass0(String name) {
- Class<?> clazz = classes0.remove(name);
+ private void removeClass(String name) {
+ Class<?> clazz = classes.remove(name);
try {
if ((clazz != null) && (ConfigurationSerializable.class.isAssignableFrom(clazz))) {
@@ -449,8 +342,8 @@ public class JavaPluginLoader implements PluginLoader {
String pluginName = jPlugin.getDescription().getName();
- if (!loaders0.containsKey(pluginName)) {
- loaders0.put(pluginName, (PluginClassLoader) jPlugin.getClassLoader());
+ if (!loaders.containsKey(pluginName)) {
+ loaders.put(pluginName, (PluginClassLoader) jPlugin.getClassLoader());
}
try {
@@ -483,18 +376,14 @@ public class JavaPluginLoader implements PluginLoader {
server.getLogger().log(Level.SEVERE, "Error occurred while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
}
- loaders0.remove(jPlugin.getDescription().getName());
+ loaders.remove(jPlugin.getDescription().getName());
if (cloader instanceof PluginClassLoader) {
PluginClassLoader loader = (PluginClassLoader) cloader;
- Set<String> names = loader.extended ? loader.getClasses() : loader.getClasses0(); // Don't warn on deprecation, but maintain overridability
+ Set<String> names = loader.getClasses();
for (String name : names) {
- if (extended) {
- removeClass(name);
- } else {
- removeClass0(name);
- }
+ removeClass(name);
}
}
}
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
index 29ec3fc4..c34fb2dc 100644
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
@@ -1,71 +1,68 @@
package org.bukkit.plugin.java;
+import java.io.File;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Level;
import org.apache.commons.lang.Validate;
-import org.bukkit.plugin.AuthorNagException;
+import org.bukkit.plugin.InvalidPluginException;
+import org.bukkit.plugin.PluginDescriptionFile;
/**
* A ClassLoader for plugins, to allow shared classes across multiple plugins
*/
-public class PluginClassLoader extends URLClassLoader {
+final class PluginClassLoader extends URLClassLoader {
private final JavaPluginLoader loader;
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
- final boolean extended = this.getClass() != PluginClassLoader.class;
-
- /**
- * Internal class not intended to be exposed
- */
- @Deprecated
- public PluginClassLoader(final JavaPluginLoader loader, final URL[] urls, final ClassLoader parent) {
- this(loader, urls, parent, null);
-
- if (loader.warn) {
- if (extended) {
- loader.server.getLogger().log(Level.WARNING, "PluginClassLoader not intended to be extended by " + getClass() + ", and may be final in a future version of Bukkit");
- } else {
- loader.server.getLogger().log(Level.WARNING, "Constructor \"public PluginClassLoader(JavaPluginLoader, URL[], ClassLoader)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- }
- loader.warn = false;
- }
- }
-
-
- PluginClassLoader(final JavaPluginLoader loader, final URL[] urls, final ClassLoader parent, final Object methodSignature) {
- super(urls, parent);
+ private final PluginDescriptionFile description;
+ private final File dataFolder;
+ private final File file;
+ final JavaPlugin plugin;
+ private JavaPlugin pluginInit;
+ private IllegalStateException pluginState;
+
+ 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);
+ }
- @Override
- public void addURL(URL url) { // Override for access level!
- super.addURL(url);
+ Class<? extends JavaPlugin> pluginClass;
+ try {
+ pluginClass = jarClass.asSubclass(JavaPlugin.class);
+ } catch (ClassCastException ex) {
+ throw new InvalidPluginException("main class `" + description.getMain() + "' does not extend JavaPlugin", ex);
+ }
+
+ plugin = pluginClass.newInstance();
+ } 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 extended ? findClass(name, true) : findClass0(name, true); // Don't warn on deprecation, but maintain overridability
+ return findClass(name, true);
}
- /**
- * @deprecated Internal method that wasn't intended to be exposed
- */
- @Deprecated
- protected Class<?> findClass(String name, boolean checkGlobal) throws ClassNotFoundException {
- if (loader.warn) {
- loader.server.getLogger().log(Level.WARNING, "Method \"protected Class<?> findClass(String, boolean)\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- loader.warn = false;
- }
- return findClass0(name, checkGlobal);
- }
-
- Class<?> findClass0(String name, boolean checkGlobal) throws ClassNotFoundException {
+ Class<?> findClass(String name, boolean checkGlobal) throws ClassNotFoundException {
if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) {
throw new ClassNotFoundException(name);
}
@@ -73,18 +70,14 @@ public class PluginClassLoader extends URLClassLoader {
if (result == null) {
if (checkGlobal) {
- result = loader.extended ? loader.getClassByName(name) : loader.getClassByName0(name); // Don't warn on deprecation, but maintain overridability
+ result = loader.getClassByName(name);
}
if (result == null) {
result = super.findClass(name);
if (result != null) {
- if (loader.extended) { // Don't warn on deprecation, but maintain overridability
- loader.setClass(name, result);
- } else {
- loader.setClass0(name, result);
- }
+ loader.setClass(name, result);
}
}
@@ -94,19 +87,20 @@ public class PluginClassLoader extends URLClassLoader {
return result;
}
- /**
- * @deprecated Internal method that wasn't intended to be exposed
- */
- @Deprecated
- public Set<String> getClasses() {
- if (loader.warn) {
- loader.server.getLogger().log(Level.WARNING, "Method \"public Set<String> getClasses()\" is Deprecated, and may be removed in a future version of Bukkit", new AuthorNagException(""));
- loader.warn = false;
- }
- return getClasses0();
+ Set<String> getClasses() {
+ return classes.keySet();
}
- Set<String> getClasses0() {
- 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 intialized!", pluginState);
+ }
+
+ pluginState = new IllegalStateException("Initial initialization");
+ this.pluginInit = javaPlugin;
+
+ javaPlugin.init(loader, loader.server, description, dataFolder, file, this);
}
}