refactor: replace reflection with direct Folia API calls#1
refactor: replace reflection with direct Folia API calls#1roomote-v0[bot] wants to merge 4 commits into
Conversation
…Adapter - Add Folia API as a provided dependency in pom.xml - Add PaperMC repository for Folia API resolution - Rewrite SchedulerAdapter to use direct API calls instead of reflection - Isolate Folia-specific code in a static inner class (FoliaScheduling) so JVM only loads Folia types when running on a Folia server - Remove all reflection (Method, Class.forName, invoke) from scheduler code - Maintain identical public API so callers require no changes
The latest commit (47d512e) restores
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
| static { | ||
| boolean folia = false; | ||
| try { | ||
| Class.forName("io.papermc.paper.threadedregions.scheduler.AsyncScheduler"); |
There was a problem hiding this comment.
AsyncScheduler exists on Paper 1.20+ (Paper adopted the Folia scheduler APIs for forward compatibility), so IS_FOLIA will be true on modern Paper servers as well. This causes the plugin to take the Folia scheduling path on Paper, which happens to work today but is fragile since it depends on Paper's compatibility layer rather than the native Bukkit scheduler. The standard way to detect Folia specifically is to check for a Folia-only class like io.papermc.paper.threadedregions.RegionizedServer.
| Class.forName("io.papermc.paper.threadedregions.scheduler.AsyncScheduler"); | |
| Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); |
Fix it with Roo Code or mention @roomote and request a fix.
| long delayTicks = mainConfig.getInt(Setting.CONFIRM_TIMEOUT.getConfigPath()) * 20L; | ||
| task = SchedulerAdapter.runForEntity(ChatColor.getPlugin(), player, () -> { | ||
| player.sendMessage(M.PREFIX + M.DID_NOT_CONFIRM); | ||
| confirmationsManager.removeConfirmingPlayer(player); | ||
| }, mainConfig.getInt(Setting.CONFIRM_TIMEOUT.getConfigPath()) * 20L); | ||
| }, delayTicks); |
There was a problem hiding this comment.
On Folia, entity.getScheduler().runDelayed() is called with a null retired callback (the third argument inside FoliaScheduling.runForEntity). If the player disconnects before the timeout fires, the task is silently discarded and confirmationsManager.removeConfirmingPlayer(player) never runs. Since there is no PlayerQuitEvent handler that cleans up confirming players either, the entry leaks in the confirmingPlayers map for the lifetime of the server. The retired callback should call removeConfirmingPlayer to handle this case.
Fix it with Roo Code or mention @roomote and request a fix.
| private final ChatColor plugin; | ||
|
|
||
| private BukkitTask task; | ||
| private SchedulerAdapter.TaskWrapper task; |
There was a problem hiding this comment.
SchedulerAdapter.java was deleted in the latest commit (825ac0d) but this file, ConfirmScheduler, and SqlStorageImpl still reference it (TaskWrapper, runTimer, runForEntity, runAsync). The project will not compile. The deletion appears to be accidental and the file needs to be restored.
Fix it with Roo Code or mention @roomote and request a fix.
Replaces all reflection-based Folia scheduler calls with direct API calls, as requested.
Changes
dev.folia:folia-apias aprovideddependency so Folia types are available at compile timeFoliaScheduling) so the JVM only loads Folia types when actually running on a Folia server. On Paper/Spigot servers, those classes are never touched.How it works
Java lazily loads classes -- the
FoliaSchedulinginner class (which referencesScheduledTask,getGlobalRegionScheduler(), etc.) is only loaded by the JVM when one of its static methods is called. Since those methods are only called whenIS_FOLIAis true, Paper/Spigot servers never trigger class loading of Folia types.What was removed
java.lang.reflect.Methodfields and invocationsClass.forName()lookupsinitializeFoliaReflection()methodFoliaTaskWrapper(replaced with a typed version)The public API (
runTimer,runLater,runAsync,runForEntity,TaskWrapper) is unchanged, so no caller modifications are needed.View task on Roo Code Cloud