Supporting Paper too
A plugin that extends FeatherPlugin is Feather-only by default. On Paper it logs a red message and disables itself. To make it work on both FeatherMC and Paper servers, opt in with one method, then keep the FeatherMC-specific code behind a check.
1. Allow Paper
Section titled “1. Allow Paper”Override allowPaper() and return true. Without this override the plugin stays Feather-only.
import dev.feathermc.feather.FeatherPlugin;
public final class MyPlugin extends FeatherPlugin {
@Override protected boolean allowPaper() { return true; }
@Override protected void onFeatherEnable() { // runs on FeatherMC and on Paper }}onFeatherEnable() and onFeatherDisable() still replace onEnable() and onDisable().
2. Keep FeatherMC features behind a check
Section titled “2. Keep FeatherMC features behind a check”Branch on FeatherSupport.isFeather() for anything that uses the FeatherMC API (Feather, the events or the config classes). Paper does not have those classes, so loading them there throws a NoClassDefFoundError.
import dev.feathermc.feather.FeatherSupport;
@Overrideprotected void onFeatherEnable() { if (FeatherSupport.isFeather()) { // Register the FeatherMC listener only here, so Paper never loads it. getServer().getPluginManager().registerEvents(new FeatherListener(), this); getLogger().info("FeatherMC features enabled."); } else { getLogger().info("Running on Paper, FeatherMC features are off."); }}Put all FeatherMC API use in separate classes, such as FeatherListener above, and only create or register them inside the isFeather() branch. A class that merely mentions an API type in a field, parameter or event handler can be loaded early and fail on Paper.
public final class FeatherListener implements Listener { @EventHandler public void onFlag(final AntiCheatFlagEvent event) { // FeatherMC-only behaviour }}3. Bundle the gate classes
Section titled “3. Bundle the gate classes”tasks.shadowJar { include("dev/feathermc/feather/FeatherSupport*.class") include("dev/feathermc/feather/FeatherPlugin*.class") // also include your own plugin classes and resources}Use compileOnly for feather-api as in the setup guide. Shadow only includes what you list, so list your own packages too, for example include("com/example/**"), and your resources such as plugin.yml.
Summary
Section titled “Summary”| You want | Do this |
|---|---|
| Runs on FeatherMC only | Extend FeatherPlugin and change nothing else. |
| Runs on FeatherMC and Paper | Override allowPaper(), bundle the two gate classes and guard FeatherMC code with FeatherSupport.isFeather(). |
Adapted from the PaperMC docs (CC BY-SA 4.0). About these docs.