Add support for private constructors in plugin main classes (#12652)

This commit is contained in:
wiicart
2025-06-23 22:50:59 -04:00
committed by GitHub
parent 1814d8b47a
commit e454fef40e
2 changed files with 20 additions and 3 deletions

View File

@@ -4,6 +4,8 @@ import com.destroystokyo.paper.util.SneakyThrow;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InaccessibleObjectException;
/**
* An <b>internal</b> utility type that holds logic for loading a provider-like type from a classloaders.
@@ -56,7 +58,14 @@ public final class ProviderUtil {
throw new ClassCastException("class '%s' does not extend '%s'".formatted(clazz, classType));
}
clazzInstance = pluginClass.getDeclaredConstructor().newInstance();
final Constructor<? extends T> constructor = pluginClass.getDeclaredConstructor();
try {
constructor.setAccessible(true); // Allow non-public constructors
} catch (final InaccessibleObjectException | SecurityException ex) {
throw new RuntimeException("Inaccessible constructor");
}
clazzInstance = constructor.newInstance();
} catch (final IllegalAccessException exception) {
throw new RuntimeException("No public constructor");
} catch (final InstantiationException exception) {

View File

@@ -6,6 +6,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InaccessibleObjectException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -91,13 +92,20 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm
try {
pluginConstructor = pluginClass.getDeclaredConstructor();
} catch (NoSuchMethodException ex) {
throw new InvalidPluginException("main class `" + description.getMain() + "' must have a public no-args constructor", ex);
throw new InvalidPluginException("main class `" + description.getMain() + "' must have a no-args constructor", ex);
}
try {
// Support non-public constructors
pluginConstructor.setAccessible(true);
} catch (InaccessibleObjectException | SecurityException ex) {
throw new InvalidPluginException("main class `" + description.getMain() + "' constructor inaccessible", ex);
}
try {
plugin = pluginConstructor.newInstance();
} catch (IllegalAccessException ex) {
throw new InvalidPluginException("main class `" + description.getMain() + "' constructor must be public", ex);
throw new InvalidPluginException("main class `" + description.getMain() + "' constructor inaccessible", ex);
} catch (InstantiationException ex) {
throw new InvalidPluginException("main class `" + description.getMain() + "' must not be abstract", ex);
} catch (IllegalArgumentException ex) {