mirror of https://github.com/Minestom/Minestom.git
123 lines
4.2 KiB
Java
123 lines
4.2 KiB
Java
package net.minestom.server.extras.selfmodification;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.net.URL;
|
|
|
|
public class MinestomExtensionClassLoader extends HierarchyClassLoader {
|
|
/**
|
|
* Root ClassLoader, everything goes through it before any attempt at loading is done inside this classloader
|
|
*/
|
|
private final MinestomRootClassLoader root;
|
|
|
|
/**
|
|
* Main of the main class of the extension linked to this classloader
|
|
*/
|
|
private final String mainClassName;
|
|
|
|
private final Logger logger = LoggerFactory.getLogger(MinestomExtensionClassLoader.class);
|
|
|
|
public MinestomExtensionClassLoader(String extensionName, String mainClassName, URL[] urls, MinestomRootClassLoader root) {
|
|
super(extensionName, urls, root);
|
|
this.root = root;
|
|
this.mainClassName = mainClassName;
|
|
}
|
|
|
|
/**
|
|
* Returns the name of the extension linked to this classloader
|
|
* @return the name of the extension linked to this classloader
|
|
*/
|
|
public String getExtensionName() {
|
|
// simply calls ClassLoader#getName as the extension name is used to name this classloader
|
|
// this method is simply for ease-of-use
|
|
return getName();
|
|
}
|
|
|
|
/**
|
|
* Returns the main class name linked to the extension responsible for this classloader.
|
|
* Used by the root classloader to let extensions load themselves in a dev environment.
|
|
* @return the main class name linked to the extension responsible for this classloader
|
|
*/
|
|
public String getMainClassName() {
|
|
return mainClassName;
|
|
}
|
|
|
|
@Override
|
|
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
|
return root.loadClass(name);
|
|
}
|
|
|
|
@Override
|
|
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
|
return root.loadClass(name, resolve);
|
|
}
|
|
|
|
/**
|
|
* Assumes the name is not null, nor it does represent a protected class
|
|
* @param name
|
|
* @return
|
|
* @throws ClassNotFoundException if the class is not found inside this classloader
|
|
*/
|
|
public Class<?> loadClassAsChild(String name, boolean resolve) throws ClassNotFoundException {
|
|
Class<?> loadedClass = findLoadedClass(name);
|
|
if(loadedClass != null) {
|
|
return loadedClass;
|
|
}
|
|
|
|
try {
|
|
// not in children, attempt load in this classloader
|
|
String path = name.replace(".", "/") + ".class";
|
|
InputStream in = getResourceAsStream(path);
|
|
if (in == null) {
|
|
throw new ClassNotFoundException("Could not load class " + name);
|
|
}
|
|
try (in) {
|
|
byte[] bytes = in.readAllBytes();
|
|
Class<?> clazz = defineClass(name, bytes, 0, bytes.length);
|
|
if (resolve) {
|
|
resolveClass(clazz);
|
|
}
|
|
return clazz;
|
|
} catch (IOException e) {
|
|
throw new ClassNotFoundException("Could not load class " + name, e);
|
|
}
|
|
} catch (ClassNotFoundException e) {
|
|
for(MinestomExtensionClassLoader child : children) {
|
|
try {
|
|
return child.loadClassAsChild(name, resolve);
|
|
} catch (ClassNotFoundException e1) {
|
|
// move on to next child
|
|
}
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void finalize() throws Throwable {
|
|
super.finalize();
|
|
logger.info("Class loader " + getName() + " finalized.");
|
|
}
|
|
|
|
/**
|
|
* Is the given class name the name of the entry point of one the extensions from this classloader chain?
|
|
* @param name the class name to check
|
|
* @return whether the given class name the name of the entry point of one the extensions from this classloader chain
|
|
* @see MinestomRootClassLoader#loadBytes(String, boolean) for more information
|
|
*/
|
|
protected boolean isMainExtensionClass(String name) {
|
|
|
|
if (mainClassName.equals(name))
|
|
return true;
|
|
|
|
for (MinestomExtensionClassLoader child : children) {
|
|
if (child.isMainExtensionClass(name)) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|