PaperMC Event Listeners with Automatic Registration
Reedwork automatically discovers and registers PaperMC and Bukkit event listeners during plugin initialization.
You continue using the standard Bukkit/Paper event API with Listener and @EventHandler.
The only Reedwork-specific step is adding @EventListener to the listener class.
This removes manual event registration while keeping your existing Paper event-handling code unchanged.
Create a Paper event listener
Section titled “Create a Paper event listener”A Reedwork event listener is a regular Bukkit/Paper Listener:
package dev.reedworkmc.examples.eventlistener.events;
import dev.reedworkmc.reedwork.annotation.EventListener;import net.kyori.adventure.text.Component;import net.kyori.adventure.text.format.NamedTextColor;import org.bukkit.entity.Player;import org.bukkit.event.EventHandler;import org.bukkit.event.Listener;import org.bukkit.event.player.PlayerJoinEvent;import org.bukkit.event.player.PlayerQuitEvent;
@EventListenerpublic final class PlayerConnectionEvents implements Listener {
@EventHandler public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer();
event.joinMessage(Component.text(player.getName() + " joined the server!", NamedTextColor.BLUE));
player.sendMessage(Component.text("Welcome to the server " + player.getName() + "!", NamedTextColor.YELLOW)); }
@EventHandler public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer();
event.quitMessage(Component.text(player.getName() + " left the server!", NamedTextColor.RED)); }}The Reedwork-specific part is the @EventListener annotation:
@EventListenerpublic final class PlayerConnectionEvents implements Listener { // ...}The annotation tells Reedwork to discover the class during package scanning.
The event handlers themselves remain standard Bukkit/Paper event handlers.
You do not need a different event API or framework-specific event classes.
Automatic event registration
Section titled “Automatic event registration”The plugin only needs to initialize Reedwork and scan the package containing the listener:
package dev.reedworkmc.examples.eventlistener;
import dev.reedworkmc.reedwork.Reedwork;import org.bukkit.plugin.java.JavaPlugin;
public final class EventListenerExample extends JavaPlugin {
@Override public void onEnable() { // Plugin startup logic Reedwork.create(this).scan("dev.reedworkmc.examples.eventlistener"); }}When Reedwork scans the package, it discovers the @EventListener class and registers it with Paper automatically.
Without Reedwork, the listener would normally need to be registered explicitly through Bukkit’s plugin manager.
With Reedwork, the registration is handled as part of component discovery.
Keep the Bukkit and Paper event API
Section titled “Keep the Bukkit and Paper event API”Reedwork does not replace the event system provided by Bukkit or Paper.
Your listener still implements:
Listenerand event methods still use:
@EventHandlerFor example:
@EventHandlerpublic void onPlayerJoin(PlayerJoinEvent event) { // ...}This means existing knowledge of Bukkit and Paper events remains directly applicable when using Reedwork.
Reedwork only handles discovering and registering the listener.
Event listeners as Reedwork components
Section titled “Event listeners as Reedwork components”Event listeners are managed by Reedwork and can therefore participate in the same dependency injection system as other Reedwork components.
For example, a listener can declare a service dependency through its constructor:
@EventListenerpublic final class PlayerConnectionEvents implements Listener {
private final PlayerService playerService;
public PlayerConnectionEvents(PlayerService playerService) { this.playerService = playerService; }
@EventHandler public void onPlayerJoin(PlayerJoinEvent event) { playerService.handleJoin(event.getPlayer()); }}Reedwork resolves the constructor dependency when it creates the listener.
This allows event handling and application services to remain separated instead of placing all plugin logic directly inside event listeners.
Learn more about dependency injection in Reedwork.
Why use automatic event registration?
Section titled “Why use automatic event registration?”Manual event registration is simple, but every listener has to be explicitly connected to the plugin.
As a Paper plugin grows, this can result in repeated registration code in the plugin’s initialization logic.
Reedwork moves that responsibility into component discovery.
The result is:
- standard Bukkit/Paper event handling
- one Reedwork annotation per managed listener
- automatic listener discovery
- automatic registration
- constructor dependency injection for listener components
Your listener remains focused on handling events while Reedwork handles the registration infrastructure.
The result
Section titled “The result”A complete Reedwork event listener can be as simple as:
@EventListenerpublic final class PlayerConnectionEvents implements Listener {
@EventHandler public void onPlayerJoin(PlayerJoinEvent event) { // Handle the event. }}There is no separate registration call for the listener.
Reedwork discovers the class during its package scan and registers it with Paper.
This makes automatic event registration a small, incremental addition to an existing Bukkit/Paper plugin.
Events and the Reedwork framework
Section titled “Events and the Reedwork framework”Event listeners are one of several component types managed by Reedwork.
The same dependency injection system can connect listeners with services, while commands can use the same constructor-based dependency model.
Explore the other Reedwork components:
- Commands — build PaperMC commands with Java annotations and automatic parameter resolution.
- Dependency Injection — resolve services and other dependencies through constructors.
- Enchantments — create and register custom Minecraft enchantments.
- Utilities — use reusable utilities for Paper plugin development.
The complete runnable event listener example is available in the ReedworkExamples repository.