Pass closable around instead of closing it straight away.
- Ensures ServerUtils can reload itself :)
This commit is contained in:
parent
75545ac156
commit
c2049503a7
5 changed files with 92 additions and 29 deletions
|
|
@ -130,7 +130,11 @@ public class ServerUtils extends JavaPlugin implements CommandExecutor {
|
||||||
return commandManager;
|
return commandManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private File[] getJars() {
|
/**
|
||||||
|
* Retrieves all files with a jar extension in the plugins/ folder.
|
||||||
|
* @return An array of jar files.
|
||||||
|
*/
|
||||||
|
public File[] getJars() {
|
||||||
File parent = getDataFolder().getParentFile();
|
File parent = getDataFolder().getParentFile();
|
||||||
if (parent == null) return new File[0];
|
if (parent == null) return new File[0];
|
||||||
return parent.listFiles(f -> f.getName().endsWith(".jar"));
|
return parent.listFiles(f -> f.getName().endsWith(".jar"));
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import net.frankheijden.serverutils.ServerUtils;
|
import net.frankheijden.serverutils.ServerUtils;
|
||||||
import net.frankheijden.serverutils.config.Messenger;
|
import net.frankheijden.serverutils.config.Messenger;
|
||||||
|
import net.frankheijden.serverutils.managers.CloseableResult;
|
||||||
import net.frankheijden.serverutils.managers.LoadResult;
|
import net.frankheijden.serverutils.managers.LoadResult;
|
||||||
import net.frankheijden.serverutils.managers.PluginManager;
|
import net.frankheijden.serverutils.managers.PluginManager;
|
||||||
import net.frankheijden.serverutils.managers.Result;
|
import net.frankheijden.serverutils.managers.Result;
|
||||||
|
|
@ -171,8 +172,9 @@ public class CommandServerUtils extends BaseCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result unloadResult = PluginManager.unloadPlugin(pluginName);
|
CloseableResult result = PluginManager.unloadPlugin(pluginName);
|
||||||
unloadResult.sendTo(sender, "unload", pluginName);
|
result.getResult().sendTo(sender, "unload", pluginName);
|
||||||
|
result.tryClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -185,8 +187,9 @@ public class CommandServerUtils extends BaseCommand {
|
||||||
@CommandPermission("serverutils.reloadplugin")
|
@CommandPermission("serverutils.reloadplugin")
|
||||||
@Description("Reloads a specified plugin.")
|
@Description("Reloads a specified plugin.")
|
||||||
public void onReloadPlugin(CommandSender sender, String pluginName) {
|
public void onReloadPlugin(CommandSender sender, String pluginName) {
|
||||||
Result result = PluginManager.reloadPlugin(pluginName);
|
CloseableResult result = PluginManager.reloadPlugin(pluginName);
|
||||||
result.sendTo(sender, "reload", pluginName);
|
result.getResult().sendTo(sender, "reload", pluginName);
|
||||||
|
result.tryClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package net.frankheijden.serverutils.managers;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class CloseableResult implements Closeable {
|
||||||
|
|
||||||
|
private Result result;
|
||||||
|
private final Closeable closeable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new closable result.
|
||||||
|
* Used for unloading / reloading a plugin.
|
||||||
|
* NB: The closable needs to be closed to fully ensure that the old plugin doesn't work anymore!
|
||||||
|
* @param result The result of the procedure
|
||||||
|
* @param closeable The closable of the procedure.
|
||||||
|
*/
|
||||||
|
public CloseableResult(Result result, Closeable closeable) {
|
||||||
|
this.result = result;
|
||||||
|
this.closeable = closeable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableResult(Result result) {
|
||||||
|
this(result, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableResult(Closeable closeable) {
|
||||||
|
this(Result.SUCCESS, closeable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableResult set(Result result) {
|
||||||
|
this.result = result;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to close the closable, essentially wrapping it with try-catch.
|
||||||
|
*/
|
||||||
|
public void tryClose() {
|
||||||
|
try {
|
||||||
|
close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
closeable.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package net.frankheijden.serverutils.managers;
|
package net.frankheijden.serverutils.managers;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -102,7 +103,7 @@ public class PluginManager {
|
||||||
* @param pluginName The plugin to unload.
|
* @param pluginName The plugin to unload.
|
||||||
* @return The result of the unload.
|
* @return The result of the unload.
|
||||||
*/
|
*/
|
||||||
public static Result unloadPlugin(String pluginName) {
|
public static CloseableResult unloadPlugin(String pluginName) {
|
||||||
return unloadPlugin(Bukkit.getPluginManager().getPlugin(pluginName));
|
return unloadPlugin(Bukkit.getPluginManager().getPlugin(pluginName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,17 +112,18 @@ public class PluginManager {
|
||||||
* @param plugin The plugin to unload.
|
* @param plugin The plugin to unload.
|
||||||
* @return The result of the unload.
|
* @return The result of the unload.
|
||||||
*/
|
*/
|
||||||
public static Result unloadPlugin(Plugin plugin) {
|
public static CloseableResult unloadPlugin(Plugin plugin) {
|
||||||
if (plugin == null) return Result.NOT_EXISTS;
|
if (plugin == null) return new CloseableResult(Result.NOT_EXISTS);
|
||||||
|
Closeable closeable;
|
||||||
try {
|
try {
|
||||||
RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin);
|
RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin);
|
||||||
RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName());
|
RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName());
|
||||||
RPluginClassLoader.clearClassLoader(RJavaPlugin.getClassLoader(plugin));
|
closeable = RPluginClassLoader.clearClassLoader(RJavaPlugin.getClassLoader(plugin));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return Result.ERROR;
|
return new CloseableResult(Result.ERROR);
|
||||||
}
|
}
|
||||||
return Result.SUCCESS;
|
return new CloseableResult(closeable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -153,9 +155,9 @@ public class PluginManager {
|
||||||
* @param pluginName The plugin to reload.
|
* @param pluginName The plugin to reload.
|
||||||
* @return The result of the reload.
|
* @return The result of the reload.
|
||||||
*/
|
*/
|
||||||
public static Result reloadPlugin(String pluginName) {
|
public static CloseableResult reloadPlugin(String pluginName) {
|
||||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||||
if (plugin == null) return Result.NOT_EXISTS;
|
if (plugin == null) return new CloseableResult(Result.NOT_EXISTS);
|
||||||
return reloadPlugin(plugin);
|
return reloadPlugin(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,27 +166,29 @@ public class PluginManager {
|
||||||
* @param plugin The plugin to reload.
|
* @param plugin The plugin to reload.
|
||||||
* @return The result of the reload.
|
* @return The result of the reload.
|
||||||
*/
|
*/
|
||||||
public static Result reloadPlugin(Plugin plugin) {
|
public static CloseableResult reloadPlugin(Plugin plugin) {
|
||||||
Result disableResult = disablePlugin(plugin);
|
Result disableResult = disablePlugin(plugin);
|
||||||
if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) return disableResult;
|
if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) {
|
||||||
|
return new CloseableResult(disableResult);
|
||||||
|
}
|
||||||
|
|
||||||
Result unloadResult = unloadPlugin(plugin);
|
CloseableResult result = unloadPlugin(plugin);
|
||||||
if (unloadResult != Result.SUCCESS) return unloadResult;
|
if (result.getResult() != Result.SUCCESS) return result;
|
||||||
|
|
||||||
File pluginFile;
|
File pluginFile;
|
||||||
try {
|
try {
|
||||||
pluginFile = RPlugin.getPluginFile(plugin);
|
pluginFile = RPlugin.getPluginFile(plugin);
|
||||||
} catch (InvocationTargetException | IllegalAccessException ex) {
|
} catch (InvocationTargetException | IllegalAccessException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return Result.ERROR;
|
return result.set(Result.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadResult loadResult = loadPlugin(pluginFile);
|
LoadResult loadResult = loadPlugin(pluginFile);
|
||||||
if (!loadResult.isSuccess()) {
|
if (!loadResult.isSuccess()) {
|
||||||
Result r = loadResult.getResult();
|
Result r = loadResult.getResult();
|
||||||
return (r == Result.NOT_EXISTS) ? Result.FILE_CHANGED : r;
|
return result.set((r == Result.NOT_EXISTS) ? Result.FILE_CHANGED : r);
|
||||||
}
|
}
|
||||||
return enablePlugin(loadResult.getPlugin());
|
return result.set(enablePlugin(loadResult.getPlugin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,8 @@ import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionPar
|
||||||
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllFields;
|
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllFields;
|
||||||
import static net.frankheijden.serverutils.reflection.ReflectionUtils.set;
|
import static net.frankheijden.serverutils.reflection.ReflectionUtils.set;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.Closeable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class RPluginClassLoader {
|
public class RPluginClassLoader {
|
||||||
|
|
@ -32,20 +31,18 @@ public class RPluginClassLoader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears and closes the provided classloader.
|
* Clears and closes the provided classloader.
|
||||||
* Remov
|
|
||||||
* @param loader The classloader instance.
|
* @param loader The classloader instance.
|
||||||
* @throws IOException When closing the loader failed.
|
* @return The Closeable object.
|
||||||
* @throws IllegalAccessException When prohibited access to the field.
|
* @throws IllegalAccessException When prohibited access to the field.
|
||||||
*/
|
*/
|
||||||
public static void clearClassLoader(ClassLoader loader) throws IOException, IllegalAccessException {
|
public static Closeable clearClassLoader(ClassLoader loader) throws IllegalAccessException {
|
||||||
if (loader == null) return;
|
if (loader == null) return null;
|
||||||
if (isInstance(loader)) {
|
if (isInstance(loader)) {
|
||||||
clearUrlClassLoader(loader);
|
clearUrlClassLoader(loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loader instanceof URLClassLoader) {
|
if (loader instanceof Closeable) return (Closeable) loader;
|
||||||
((URLClassLoader) loader).close();
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue