Ghetto module+lib loading
This commit is contained in:
parent
e97a43c9e2
commit
29b7a3cee7
@ -2,6 +2,11 @@ package cz.marwland.mc.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -18,6 +23,7 @@ import cz.marwland.mc.core.storage.StorageCredentials;
|
||||
import cz.marwland.mc.core.storage.impl.MariaDbConnectionFactory;
|
||||
import cz.marwland.mc.core.storage.impl.MySqlConnectionFactory;
|
||||
import cz.marwland.mc.core.util.ConfigUtil;
|
||||
import cz.marwland.mc.core.util.FileUtil;
|
||||
|
||||
public class MarwCore extends JavaPlugin {
|
||||
|
||||
@ -25,29 +31,33 @@ public class MarwCore extends JavaPlugin {
|
||||
private HashMap<String, Feature> features = new HashMap<>();
|
||||
private static MarwCore INSTANCE = null;
|
||||
private File modulesFolder = null;
|
||||
private File libsFolder = null;
|
||||
private ModuleClassLoader moduleClassLoader;
|
||||
private SQLStorage sqlStorage;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
INSTANCE = this;
|
||||
this.getCommand("marw").setExecutor(new MarwCommandExecutor());
|
||||
|
||||
modulesFolder = this.getModulesFolderPath().toFile();
|
||||
modulesFolder.mkdirs();
|
||||
libsFolder = this.getLibsFolderPath().toFile();
|
||||
libsFolder.mkdir();
|
||||
configManager = new ConfigManager(this);
|
||||
configManager.registerConfig("config.yml");
|
||||
configManager.loadConfig("config.yml");
|
||||
this.loadModulesAndLibs();
|
||||
this.loadDatabase();
|
||||
|
||||
modulesFolder = this.getModulesFolderPath().toFile();
|
||||
modulesFolder.mkdirs();
|
||||
this.loadAndEnableModules();
|
||||
this.getCommand("marw").setExecutor(new MarwCommandExecutor());
|
||||
this.enableModules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
this.features.forEach((k, v) -> v.onDisable());
|
||||
this.configManager.save();
|
||||
this.sqlStorage.shutdown();
|
||||
if (sqlStorage != null)
|
||||
this.sqlStorage.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,13 +66,14 @@ public class MarwCore extends JavaPlugin {
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
this.reloadConfig();
|
||||
this.features.forEach((k, v) -> v.onDisable());
|
||||
this.reloadConfig();
|
||||
this.loadModulesAndLibs();
|
||||
this.loadDatabase();
|
||||
this.loadAndEnableModules();
|
||||
this.enableModules();
|
||||
}
|
||||
|
||||
public void loadModules() {
|
||||
public void loadModulesAndLibs() {
|
||||
if (moduleClassLoader != null) {
|
||||
try {
|
||||
moduleClassLoader.close();
|
||||
@ -71,10 +82,17 @@ public class MarwCore extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
moduleClassLoader = new ModuleClassLoader();
|
||||
URLClassLoader pluginClassLoader = (URLClassLoader) this.getClassLoader();
|
||||
FileUtil.addFromDirectory(pluginClassLoader, libsFolder);
|
||||
//FileUtil.addFromDirectory(pluginClassLoader, modulesFolder);
|
||||
moduleClassLoader = new ModuleClassLoader(pluginClassLoader);
|
||||
//moduleClassLoader.addFromDirectory(libsFolder);
|
||||
moduleClassLoader.addFromDirectory(modulesFolder);
|
||||
}
|
||||
|
||||
public void enableModules() {
|
||||
for (String modClass : configManager.getConfig("config.yml").getStringList("modules")) {
|
||||
//Feature f = FileUtil.doConstructor((URLClassLoader) this.getClassLoader(), modClass, this);
|
||||
Feature f = moduleClassLoader.doConstructor(modClass, this);
|
||||
if (f == null)
|
||||
continue;
|
||||
@ -82,10 +100,6 @@ public class MarwCore extends JavaPlugin {
|
||||
this.addFeature(f);
|
||||
this.getLogger().log(Level.INFO, "Loaded " + f.getName() + " @ " + modClass);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadAndEnableModules() {
|
||||
this.loadModules();
|
||||
configManager.load();
|
||||
this.features.forEach((k, v) -> v.onEnable());
|
||||
}
|
||||
@ -114,6 +128,10 @@ public class MarwCore extends JavaPlugin {
|
||||
return this.getDataFolder().toPath().resolve("modules");
|
||||
}
|
||||
|
||||
public Path getLibsFolderPath() {
|
||||
return this.getDataFolder().toPath().resolve("libs");
|
||||
}
|
||||
|
||||
public ModuleClassLoader getModuleClassLoader() {
|
||||
return this.moduleClassLoader;
|
||||
}
|
||||
@ -141,7 +159,7 @@ public class MarwCore extends JavaPlugin {
|
||||
props
|
||||
);
|
||||
|
||||
String method = cfg.getString("method");
|
||||
String method = cfg.getString("dataSource.method");
|
||||
if (method.equalsIgnoreCase("mariadb")) {
|
||||
this.sqlStorage = new SQLStorage(new MariaDbConnectionFactory(creds));
|
||||
} else if (method.equalsIgnoreCase("mysql")) {
|
||||
|
@ -15,8 +15,8 @@ public class ModuleClassLoader extends URLClassLoader {
|
||||
|
||||
private ArrayList<JarFile> jars = new ArrayList<>();
|
||||
|
||||
public ModuleClassLoader() {
|
||||
super(new URL[] { }, ModuleClassLoader.class.getClassLoader());
|
||||
public ModuleClassLoader(ClassLoader parent) {
|
||||
super(new URL[] { }, parent);
|
||||
}
|
||||
|
||||
public void addFile(File file) throws IOException {
|
||||
|
99
src/cz/marwland/mc/core/util/FileUtil.java
Normal file
99
src/cz/marwland/mc/core/util/FileUtil.java
Normal file
@ -0,0 +1,99 @@
|
||||
package cz.marwland.mc.core.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import cz.marwland.mc.core.features.Feature;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static String readFileFromJAR(Class<?> parent, String path) throws IOException {
|
||||
InputStream in = parent.getResourceAsStream(path);
|
||||
if (in == null) {
|
||||
System.err.println("Invalid path: " + path);
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) != -1) {
|
||||
result.write(buffer, 0, length);
|
||||
}
|
||||
String ret = result.toString(StandardCharsets.UTF_8.name() );
|
||||
in.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void addFromDirectory(URLClassLoader cl, File modDir) {
|
||||
if (!modDir.isDirectory())
|
||||
throw new IllegalArgumentException("Provided 'modDir' argument is not a directory: " + modDir.getPath());
|
||||
|
||||
for (File mod : modDir.listFiles()) {
|
||||
if (mod.isDirectory())
|
||||
continue;
|
||||
int lastdot = mod.getName().lastIndexOf('.');
|
||||
if (lastdot < 0)
|
||||
continue;
|
||||
|
||||
if (!mod.getName().substring(lastdot + 1).equalsIgnoreCase("jar"))
|
||||
continue;
|
||||
|
||||
try {
|
||||
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{ URL.class });
|
||||
method.setAccessible(true);
|
||||
method.invoke(cl, new Object[]{ mod.toURI().toURL() });
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(">>> Loaded: " + mod.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static Feature doConstructor(ClassLoader cl, String classPath)
|
||||
throws ClassNotFoundException, ClassCastException, IllegalAccessException, InstantiationException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||
Class<?> jarClass;
|
||||
jarClass = Class.forName(classPath, true, cl);
|
||||
|
||||
Class<? extends Feature> pluginClass;
|
||||
pluginClass = jarClass.asSubclass(Feature.class);
|
||||
|
||||
return pluginClass.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
public static Feature doConstructor(ClassLoader cl, String classPath, JavaPlugin plugin) {
|
||||
try {
|
||||
return doConstructor(cl, classPath);
|
||||
} catch (ClassNotFoundException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Cannot find class '" + classPath + "'!");
|
||||
} catch (ClassCastException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Class '" + classPath + "' does not extend Feature!");
|
||||
} catch (IllegalAccessException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "No public constructor in '" + classPath + "'!");
|
||||
} catch (InstantiationException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Cannot instantiate '" + classPath + "'!");
|
||||
} catch (IllegalArgumentException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Illegal arguments to the constructor of '" + classPath + "'!");
|
||||
} catch (InvocationTargetException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error occured whilst initializing '" + classPath + "'!");
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Class '" + classPath + "' does not have a public constructor!");
|
||||
} catch (SecurityException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "SecurityException occured whilst initializing '" + classPath + "'!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user