Skip to content

Add experimental Velocity plugin reload support - #95

Open
MrSimpleJS wants to merge 93 commits into
Test-Account666:masterfrom
MrSimpleJS:Velocity
Open

Add experimental Velocity plugin reload support#95
MrSimpleJS wants to merge 93 commits into
Test-Account666:masterfrom
MrSimpleJS:Velocity

Conversation

@MrSimpleJS

@MrSimpleJS MrSimpleJS commented Jul 14, 2026

Copy link
Copy Markdown

This PR adds experimental runtime plugin management for Velocity 3.4.0 through 4.1.0. Newer versions use the Velocity 4.x adapter after runtime capability checks.

PlugManX can now load, unload, enable, disable, restart, and reload compatible Velocity plugins without restarting the proxy.

Java 25 or newer is required. Velocity has no official runtime reload API, so this development build uses capability-checked internal APIs that may require updates when Velocity changes.

Features:

  • Runtime loading, unloading, enabling, disabling, restarting, and reloading
  • Support for Velocity 3.4.0 through 4.1.0
  • Version-specific adapters for Velocity 3.4+ and 4.x
  • Startup validation of required internal classes, fields, methods, and registries
  • Automatic capability checks for newer Velocity builds
  • Reload is disabled safely when required runtime internals are incompatible
  • Serialized operations to prevent concurrent registry and classloader changes
  • Dependency validation and dependency-aware bulk operation ordering
  • Plugin initialization and shutdown lifecycle event handling
  • Fault-tolerant cleanup that continues when individual steps fail
  • Cleanup of listeners, scheduled tasks, commands, messaging channels, registries, and classloaders
  • Classloader-aware packet registry cleanup
  • Packet registry snapshots and per-plugin registration delta tracking
  • Safe removal of exactly the packet mappings added during plugin initialization
  • Fallback cleanup for late or asynchronously registered packet mappings
  • Runtime validation of Velocity StateRegistry and packet registry layouts
  • Protection against duplicate packet registrations after reload
  • Tracking of plugin-owned messaging channels
  • Detection of remaining threads, registrations, classloaders, and other unload leaks
  • Detailed reporting of failed cleanup steps
  • Automatic rollback to the previous JAR when loading or reloading fails
  • Recovery from partial unload and cleanup failures
  • Protection for critical plugins with Velocity-only --force support
  • Console-only Velocity commands to prevent conflicts with backend PlugManX installations
  • Velocity-specific configuration, messages, help output, and plugin lists
  • Colored console output and development-build startup diagnostics
  • Reload timings and detailed diagnostics with velocityReloadDebug: true
  • Crash dumps with unique IDs for runtime and cleanup failures

Showcase:
https://www.youtube.com/watch?v=X3AOtK3jhPo

Download for Velocity:
PlugManX-3.1.0.Velocity.zip

This build adds runtime reload support for Paper plugins using paper-plugin.yml, including Paper provider loading, Paper plugin cleanup, command/listener cleanup, and compatibility fixes for newer Paper versions. It also includes a configurable paperReloadDebug option for troubleshooting Paper reload issues.
Features:
Supports loading/reloading Paper plugins with paper-plugin.yml
Uses Paper runtime provider loading instead of Bukkit-only loading
Cleans up Paper plugin manager/provider storage on unload
Handles modern Paper classloader differences
Skips unsupported runtime bootstrap/loader entrypoints safely
Optional debug logging via paperReloadDebug: true
Built for modern Paper/Spigot 1.20+ / 1.21.x / 26.x servers
Addressed the review comments:
- Reverted the local Windows-only licenseResolver path back to the project-relative one.
- Restored Lombok @requiredargsconstructor in PaperInitializer.
- Added defensive handling for optional dependency linkage errors during Paper command cleanup.
Paper plugins now reload through Paper's provider/entrypoint system and re-run the COMMANDS lifecycle after enabling, fixing missing Brigadier commands after reload.
… enable handling, better diagnostics, and more robust shutdown cleanup.

Changes
Added a plugin load preflight check before /plugman load:
verifies the plugin jar exists
verifies plugin.yml or paper-plugin.yml is readable
prevents loading a plugin that is already loaded
checks obvious required dependencies before loading

Improved load failure messages:
missing required dependencies now show a clear message
invalid plugin files fail before Paper reflection logic runs where possible

Improved Paper /plugman enable behavior:
Paper no longer re-enables a disabled plugin through the old classloader
/plugman enable <plugin> now uses a safer restart-style flow internally:unload the disabled plugin
load it fresh from disk
return the normal enable success message

Added support for operation-specific message arguments through PluginResult.

Improved shutdown cleanup:
reflection caches are cleared before the service registry is cleared
cleanup is protected against late shutdown classloader/linkage issues

Improved Paper warning output:
Paper warning now includes version information
detailed Paper reload diagnostics are only shown when paperReloadDebug is enabled
warning output uses the console sender so colors render correctly on Paper

Reduced noisy Paper load stacktraces:
full Paper load stacktraces are only logged when paperReloadDebug is enabled
otherwise PlugManX logs a short warning
Improve the Paper startup warning to display the detected server software and version instead of always reporting Paper.
This PR improves Paper plugin reload support by setting the Paper command lifecycle owner context during plugin enable, preventing `No lifecycle owner context is set` errors for plugins registering Paper commands in `onEnable`. (see issue Test-Account666#76)

It also updates `/plugman list` to show Paper and Bukkit plugins in separate groups, adds the new message keys to all bundled message files, and extends the v4 config migration to backfill missing message entries without overwriting existing custom messages.
- Added `MessageMigrationService` to keep message migration logic out of `PlugManConfigurationManager`
- Automatically adds missing v4 message keys to existing message files without overwriting custom values
- Adds missing `list.paper`, `list.bukkit`, `enable.failed`, and `load.missing-dependencies` messages
- Added fallback to bundled default messages when old `messages.yml` files are missing newer keys
- Prevents `Error: '<key>' not found in messages.yml` for keys that exist in the bundled defaults
- Hardened reflection cache cleanup during plugin shutdown
- Avoids `NoClassDefFoundError` during server stop by resolving cache classes lazily
Reload/restart now unloads dependent plugins first, reloads the target, then restores dependents in order.

Command syncing is deferred until the chain finishes to avoid Paper async command-map errors.

Example: this prevents classloader issues when reloading CMI while CMIEInjector still references the old CMI instance.
…plugin description"

I also added a confirmation notification for “Restart All” and “Reload All”.

Translations will be added later.
Added new keys: all-failed, blocked-dependents, confirm-all, missing-dependencies
Adds /plugman deps <plugin> to show dependencies and dependent plugins, including tab completion and translated messages.

I think everything is done ^^
Adds safer Paper plugin loading/reloading, dependency-aware reload/restart handling, /plugman deps, /plugman reloadmode
The Paper plugin loader now only registers Maven libraries on supported newer Paper versions (`1.21` through `26.2`). On Paper 1.20 it skips library loading, preventing startup failures like missing `com.fasterxml.jackson.core.Versioned` or invalid relocated Maven coordinates.

Also keeps the shaded dependencies relocated inside the jar, so PlugManX can start even when Paper library resolution is unavailable or unreliable.
Also keeps the cleanup scoped to the unloaded plugin only, so recipes from other plugins or Minecraft itself are not touched.
Added COMPILE_SCOPE = "compile"
…lugin path directly when `FileProviderSource#prepareContext` is not available.

Paper 1.20 does not expose a compatible `FileProviderSource#prepareContext(...)` method, which caused runtime reloads of Paper plugins to fail during provider setup. This change falls back to passing the plugin path directly into provider registration when `prepareContext` is unavailable, allowing Paper plugin reloads to continue on 1.20 while keeping the existing prepareContext path for newer Paper builds.
Fixes Paper plugin reloads by keeping existing provider dependency context while only loading the target plugin provider. This prevents missing dependency errors and duplicate provider reloads during runtime reload.
… plugins.

Paper 1.20 uses `getDependencyTree()` instead of `createDependencyTree()` and exposes multiple `MetaDependencyTree.add(...)` overloads. This update supports both dependency tree methods and selects the correct `add(PluginProvider)` overload, preventing Paper reload failures for plugins like EconomyShopGUI on 1.20.
@Test-Account666

Copy link
Copy Markdown
Owner

I plan on merging this week.

I'm sorry for the delay, but I didn't want to push multiple huge features/changes in quick succession

@MrSimpleJS

Copy link
Copy Markdown
Author

No problem at all, take your time. Thanks for the update—I understand not wanting to merge several large changes too quickly.

Velocity remains a separate JAR because it uses a different plugin system and requires Java 25, while Bungee, Bukkit, and Paper use Java 21. Combining them into one JAR would not be reliable due to loader, dependency, and descriptor conflicts.

@Test-Account666

Copy link
Copy Markdown
Owner

Technically, we could lower the target java version.
Velocity would still load the plugin just fine.

(JDK 25 would only be needed at compile time in that case)

@Test-Account666

Test-Account666 commented Sep 5, 2026

Copy link
Copy Markdown
Owner

One question about #90, what was the reason for replaying Join Events again?
Because it does seem rather problematic for some plugins (Like ones that teleport users to spawn on login)

@Zoriot

Zoriot commented Sep 6, 2026

Copy link
Copy Markdown

What's left needed for merging?

@Test-Account666

Test-Account666 commented Sep 6, 2026

Copy link
Copy Markdown
Owner

What's left needed for merging?

I don't see any immediate issues.

The main delay was to not introduce too many big changes at once.
I'll merge this PR today (Just gotta get to my PC)

@Test-Account666

Copy link
Copy Markdown
Owner

Hmmm, I just tested this on Velocity 4.1.2-SNAPSHOT-27:

PMX-VEL-20260906-161357-168-F262CEFA.log
log1
log2

@Test-Account666

Copy link
Copy Markdown
Owner

Not sure if this is an issue specific to the plugin I tested though

Fix Velocity plugin reloads by recovering plugin registrations during cleanup and preventing duplicate Guice container bindings.
@MrSimpleJS

Copy link
Copy Markdown
Author

should be fixed now.
try it please.

@Test-Account666

Copy link
Copy Markdown
Owner

latest.log
Commands are still leaking. At least with this plugin

@Test-Account666

Copy link
Copy Markdown
Owner

@MrSimpleJS

MrSimpleJS commented Sep 6, 2026

Copy link
Copy Markdown
Author

It works for me?

cmds too:
image

see:
latest (4).log

@Test-Account666

Copy link
Copy Markdown
Owner

It works for me?

cmds too: image

see: latest (4).log

Commands can still be executed even after the plugin has been unloaded

@Test-Account666

Test-Account666 commented Sep 6, 2026

Copy link
Copy Markdown
Owner
image

As expected, this is an issue specific to SkinRestorer. Unsure if it's worth it to fix

@MrSimpleJS

Copy link
Copy Markdown
Author

@Zoriot

Zoriot commented Sep 7, 2026

Copy link
Copy Markdown

@MrSimpleJS can you resolve the merge conflicts?

# Conflicts:
#	README.md
#	plugman-assembly/pom.xml
#	plugman-core/src/main/java/core/com/rylinaux/plugman/commands/executables/ListCommand.java
#	plugman-paper/src/main/java/paper/com/rylinaux/plugman/pluginmanager/ModernPaperPluginManager.java
#	plugman-paper/src/main/java/paper/com/rylinaux/plugman/pluginmanager/PaperPluginManager.java
@sonarqubecloud

sonarqubecloud Bot commented Sep 8, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Publish Velocity Build to Modrinth

3 participants