PluginBridge
Class lookup across the classloaders of a hybrid server (Silkard, Youer, ...), reached from MaskingClassLoader.SnippetLoader once nothing in the host has the name.
Reflective throughout: common links only the JDK and Minecraft, while Bukkit either exists on the game loader at runtime or does not exist at all. The reflective handles are resolved once; the plugin list never is — it is read live per lookup, so enabling, disabling or reloading a plugin needs no invalidation.
There are more loaders than plugins. Two shapes hang one off the side of a plugin loader, both CHILDREN of it, so walking parents misses both: libraryLoader (the plugin's Maven libraries:, a field on the loader) and jar-in-jar (a nested implementation jar extracted at startup, then fed downloaded dependencies at runtime — only the plugin object holds it). collectFieldLoaders finds both by reading each field VALUE and asking which loader defined it. Not the field TYPE: LuckPerms declares its bootstrap field as LoaderBootstrap, so a type-based search finds nothing.
Only loaders the host cannot already reach belong here — this runs last, after masking, the game loader and its parents have all missed. The scan subtracts that chain explicitly, because a plugin loader's JavaPluginLoader field is defined by the server loader: left in, it drags the whole server classpath along behind it.
Types
Functions
o: per field, the loader that defined its value — or the value itself, when it already is a loader.PluginManager covers both plugin families: on Paper the legacy SimplePluginManager forwards getPlugins() to the Paper implementation, whose list holds legacy and Paper plugins alike.