move reflect fields in Extension to ExtensionClassLoader (#1478)

This commit is contained in:
Huynh Tien 2022-10-25 22:11:59 +07:00 committed by GitHub
parent 6316eeb90e
commit 632922bce5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 64 deletions

View File

@ -116,7 +116,7 @@ public final class DiscoveredExtension {
void createClassLoader() {
Check.stateCondition(classLoader != null, "Extension classloader has already been created");
final URL[] urls = this.files.toArray(new URL[0]);
classLoader = new ExtensionClassLoader(this.getName(), urls);
classLoader = new ExtensionClassLoader(this.getName(), urls, this);
}
@NotNull

View File

@ -17,16 +17,6 @@ import java.util.HashSet;
import java.util.Set;
public abstract class Extension {
// Set by reflection
@SuppressWarnings("unused")
private DiscoveredExtension origin;
// Set by reflection
@SuppressWarnings("unused")
private Logger logger;
// Set by reflection
@SuppressWarnings("unused")
private EventNode<Event> eventNode;
/**
* List of extensions that depend on this extension.
*/
@ -56,9 +46,16 @@ public abstract class Extension {
}
ExtensionClassLoader getExtensionClassLoader() {
if (getClass().getClassLoader() instanceof ExtensionClassLoader extensionClassLoader) {
return extensionClassLoader;
}
throw new IllegalStateException("Extension class loader is not an ExtensionClassLoader");
}
@NotNull
public DiscoveredExtension getOrigin() {
return origin;
return getExtensionClassLoader().getDiscoveredExtension();
}
/**
@ -68,11 +65,11 @@ public abstract class Extension {
*/
@NotNull
public Logger getLogger() {
return logger;
return getExtensionClassLoader().getLogger();
}
public @NotNull EventNode<Event> getEventNode() {
return eventNode;
return getExtensionClassLoader().getEventNode();
}
public @NotNull Path getDataDirectory() {

View File

@ -1,7 +1,11 @@
package net.minestom.server.extensions;
import net.minestom.server.MinecraftServer;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventNode;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.net.URL;
@ -11,13 +15,18 @@ import java.util.List;
public final class ExtensionClassLoader extends URLClassLoader {
private final List<ExtensionClassLoader> children = new ArrayList<>();
private final DiscoveredExtension discoveredExtension;
private EventNode<Event> eventNode;
private Logger logger;
public ExtensionClassLoader(String name, URL[] urls) {
public ExtensionClassLoader(String name, URL[] urls, DiscoveredExtension discoveredExtension) {
super("Ext_" + name, urls, MinecraftServer.class.getClassLoader());
this.discoveredExtension = discoveredExtension;
}
public ExtensionClassLoader(String name, URL[] urls, ClassLoader parent) {
public ExtensionClassLoader(String name, URL[] urls, ClassLoader parent, DiscoveredExtension discoveredExtension) {
super("Ext_" + name, urls, parent);
this.discoveredExtension = discoveredExtension;
}
@Override
@ -55,4 +64,29 @@ public final class ExtensionClassLoader extends URLClassLoader {
return null;
}
public DiscoveredExtension getDiscoveredExtension() {
return discoveredExtension;
}
public EventNode<Event> getEventNode() {
if (eventNode == null) {
eventNode = EventNode.all(discoveredExtension.getName());
MinecraftServer.getGlobalEventHandler().addChild(eventNode);
}
return eventNode;
}
public Logger getLogger() {
if (logger == null) {
logger = LoggerFactory.getLogger(discoveredExtension.getName());
}
return logger;
}
void terminate() {
if (eventNode != null) {
MinecraftServer.getGlobalEventHandler().removeChild(eventNode);
}
}
}

View File

@ -5,8 +5,6 @@ import net.minestom.dependencies.DependencyGetter;
import net.minestom.dependencies.ResolvedDependency;
import net.minestom.dependencies.maven.MavenRepository;
import net.minestom.server.ServerProcess;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventNode;
import net.minestom.server.utils.PropertyUtils;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.ApiStatus;
@ -17,7 +15,6 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.file.Path;
@ -322,47 +319,6 @@ public class ExtensionManager {
return null;
}
// Set extension origin to its DiscoveredExtension
try {
Field originField = Extension.class.getDeclaredField("origin");
originField.setAccessible(true);
originField.set(extension, discoveredExtension);
} catch (IllegalAccessException e) {
// We made it accessible, should not occur
} catch (NoSuchFieldException e) {
LOGGER.error("Main class '{}' in '{}' has no description field.", mainClass, extensionName, e);
return null;
}
// Set logger
try {
Field loggerField = Extension.class.getDeclaredField("logger");
loggerField.setAccessible(true);
loggerField.set(extension, LoggerFactory.getLogger(extensionClass));
} catch (IllegalAccessException e) {
// We made it accessible, should not occur
serverProcess.exception().handleException(e);
} catch (NoSuchFieldException e) {
// This should also not occur (unless someone changed the logger in Extension superclass).
LOGGER.error("Main class '{}' in '{}' has no logger field.", mainClass, extensionName, e);
}
// Set event node
try {
EventNode<Event> eventNode = EventNode.all(extensionName); // Use the extension name
Field loggerField = Extension.class.getDeclaredField("eventNode");
loggerField.setAccessible(true);
loggerField.set(extension, eventNode);
serverProcess.eventHandler().addChild(eventNode);
} catch (IllegalAccessException e) {
// We made it accessible, should not occur
serverProcess.exception().handleException(e);
} catch (NoSuchFieldException e) {
// This should also not occur
LOGGER.error("Main class '{}' in '{}' has no event node field.", mainClass, extensionName, e);
}
// add dependents to pre-existing extensions, so that they can easily be found during reloading
for (String dependencyName : discoveredExtension.getDependencies()) {
Extension dependency = extensions.get(dependencyName.toLowerCase());
@ -716,7 +672,7 @@ public class ExtensionManager {
for (String dependentID : dependents) {
Extension dependentExt = extensions.get(dependentID.toLowerCase());
if ( dependentExt != null ) { // check if extension isn't already unloaded.
if (dependentExt != null) { // check if extension isn't already unloaded.
LOGGER.info("Unloading dependent extension {} (because it depends on {})", dependentID, extensionName);
unload(dependentExt);
}
@ -730,9 +686,7 @@ public class ExtensionManager {
ext.preTerminate();
ext.terminate();
// Remove event node
EventNode<Event> eventNode = ext.getEventNode();
serverProcess.eventHandler().removeChild(eventNode);
ext.getExtensionClassLoader().terminate();
ext.postTerminate();