PluginEvents called out of order.
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 3.5k
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 11
Description
Expected behavior
I expect to see the events for PluginEnableEvent and PluginDisableEvent reflect the reality of the situation, in that the plugin failed during enablement.
Either the enable event should not be thrown if the event failed to initialize, or the events called in the correct order.
Observed/Actual behavior
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Loading Paper-Test-Plugin-watcher v1.0.0-SNAPSHOT
[22:29:48 INFO]: [Paper-Test-Plugin-stopper] Loading Paper-Test-Plugin-stopper v1.0.0-SNAPSHOT
[22:29:48 INFO]: Server permissions file permissions.yml is empty, ignoring it
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Enabling Paper-Test-Plugin-watcher v1.0.0-SNAPSHOT
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-watcher::PluginEnableEvent
[22:29:48 INFO]: [Paper-Test-Plugin-stopper] Enabling Paper-Test-Plugin-stopper v1.0.0-SNAPSHOT
[22:29:48 INFO]: [Paper-Test-Plugin-stopper] Disabling Paper-Test-Plugin-stopper v1.0.0-SNAPSHOT
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-stopper::PluginDisableEvent
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-stopper::PluginEnableEvent
[22:29:48 INFO]: Preparing level "world"
[22:29:49 INFO]: Preparing start region for dimension minecraft:overworld
[22:29:50 INFO]: Time elapsed: 586 ms
[22:29:50 INFO]: Preparing start region for dimension minecraft:the_nether
[22:29:50 INFO]: Time elapsed: 310 ms
[22:29:50 INFO]: Preparing start region for dimension minecraft:the_end
[22:29:51 INFO]: Time elapsed: 566 ms
[22:29:51 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-watcher = true
[22:29:51 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-stopper = false
Note that enable and disable logging lines are in the correct order, but the event is not.
[22:29:48 INFO]: [Paper-Test-Plugin-stopper] Enabling Paper-Test-Plugin-stopper v1.0.0-SNAPSHOT
[22:29:48 INFO]: [Paper-Test-Plugin-stopper] Disabling Paper-Test-Plugin-stopper v1.0.0-SNAPSHOT
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-stopper::PluginDisableEvent
[22:29:48 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-stopper::PluginEnableEvent
Note that the status of the stopper is correctly disabled at server load time.
[22:29:51 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-watcher = true
[22:29:51 INFO]: [Paper-Test-Plugin-watcher] Paper-Test-Plugin-stopper = false
Steps/models to reproduce
Watcher: (Note: Stopper should probably depend on Watcher)
package io.papermc.paper.testplugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.event.server.PluginEvent;
import org.bukkit.event.server.ServerLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
import java.util.logging.Level;
public final class TestPluginWatcher extends JavaPlugin implements Listener {
@Override
public void onEnable() {
this.getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
private void onPluginEnableEvent(final PluginEnableEvent e) {
this.onPluginEvent(e);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
private void onPluginDisableEvent(final PluginDisableEvent e) {
this.onPluginEvent(e);
}
private void onPluginEvent(final PluginEvent e) {
this.getLogger().log(Level.INFO, e.getPlugin().getName()+"::"+e.getEventName());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
private void onReady(ServerLoadEvent e) {
Arrays.stream(this.getServer().getPluginManager().getPlugins())
.map(p -> p.getName()+" = "+this.getServer().getPluginManager().isPluginEnabled(p))
.forEach(s -> this.getLogger().log(Level.INFO, s));
}
}
Stopper:
package io.papermc.paper.testplugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
import java.util.logging.Level;
public final class TestPluginStopper extends JavaPlugin implements Listener {
@Override
public void onEnable() {
this.getServer().getPluginManager().disablePlugin(this);
}
Plugin and Datapack List
Just the 2 listed above.
Paper version
Latest, at time of writing:
[22:37:31 INFO]: This server is running Paper version null (MC: 1.18.1) (Implementing API version 1.18.1-R0.1-SNAPSHOT) (Git: null on null)
Unknown version, custom build?
Other
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the ordering with the TestPluginWatcher and TestPluginStopper entry points, focusing on JavaPlugin.onEnable(), PluginManager.disablePlugin(), PluginEnableEvent, and PluginDisableEvent. Trace the plugin lifecycle and event dispatch to determine why disable is observed before enable, then verify that the emitted events match the logged plugin state and add regression coverage if the repository provides a suitable test location.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100