Troubleshooting & FAQ
Build problems
cannot access org.bukkit.* on every import
The build is running on a JDK older than 25. Paper ships Java 25 class files, which older compilers cannot read. Set JDK 25 in your IDE project settings, your JAVA_HOME, and your CI image, and set maven.compiler.source and target (or release) to 25.
The Paper dependency does not resolve
A version range such as [26.2.build,) resolves to nothing, because Paper versions carry a -stable qualifier. Pin an exact version such as 26.2.build.123-stable.
Dialog code fails to compile, mentioning DialogLike
An older Adventure is pinned somewhere in your build. paper-api manages Adventure through its BOM, and the Dialog API needs a newer version than older pins provide. Remove any explicit adventure-api version from your pom.xml, and check mvn dependency:tree for another dependency dragging an old one in.
JitPack build fails
JitPack builds with the JDK named in the jitpack.yml of the commit it builds. Current StoneLib pins OpenJDK 25 there; a commit that lacks the file, or pins an older JDK, cannot compile against the current Paper API. Open the build log on JitPack's site for the exact error, and try a newer tag or a commit hash.
My plugin jar is huge
sqlite-jdbc arrives transitively and carries native libraries for many platforms. If you do not use SqliteRepository, exclude it. See Installation.
Runtime problems
NoClassDefFoundError for a StoneLib class
StoneLib was not shaded into your jar. Remember it is a library, not a plugin: it must be inside your plugin jar. Check that the shade plugin runs in the package phase, and that you deployed the shaded jar rather than the original- one.
ClassCastException, NoSuchMethodError, or odd behaviour with two plugins that both use StoneLib
The plugins shade StoneLib without relocating it, so the same class names exist in both jars and one plugin can end up using the other's copy, which may be a different version. Relocate dev.anchorlight.stonelib, dev.dejvokep.boostedyaml, and com.zaxxer.hikari into a package unique to each plugin. See Shading and relocation.
No suitable driver found for jdbc:mysql://...
StoneLib does not bundle a MySQL driver. Add it under libraries in plugin.yml. See MySQL.
The server hangs for a few seconds on enable
Creating a ConnectionPool opens a first connection, and waits up to the connection timeout if the database is slow or unreachable. Check the host and credentials. If the database is sometimes slow to answer, lower connection-timeout-ms so a failure is quick.
The server lags when data saves
A blocking call is running on the main thread. MySqlRepository.save, SqliteRepository.save, and every ConnectionPool method wait on the database. Run them through SchedulerService.runAsync or supplyAsync. Threading Rules lists every blocking call.
Messages show [Missing message: some_key]
The key is missing from the server's messages.yml. Check:
- The key exists in the
messages.ymlbundled in your jar. New keys are merged from there on load. - The key name matches exactly, including case and nesting.
menu.titlemeans atitlekey inside amenusection. - A title's subtitle key exists.
showTitleshows the missing-message text for an absent key, so give an unused subtitle an empty value.
New config keys do not appear in the server's file
ConfigUpdater merges keys from the copy bundled in the jar. Check that the new key is in src/main/resources/, that the jar you deployed was rebuilt, and look for Could not update '<file>' in the log, which means the merge failed and the old file was left as it was.
A renamed config key lost its value
A relocation needs versioning, and the bundled file needs a higher config-version than the server's copy. Add config-version to the bundled file, increase it, and declare the relocation for the new version. ConfigManager cannot declare relocations; call ConfigUpdater.update with your settings. See Versioned migration.
ConfigValidator replaced a value that looks correct
The decimal validators, isValidDouble, isValidPercent, isValidPitch, and isValidYaw, reject whole numbers because YAML reads 1 as an integer. Write 1.0.
Menu items can be taken out
MenuListener is not registered, or the menu was not opened through MenuHolder. Register the listener once in onEnable, and open menus with MenuHolder.open.
A dialog does not appear
show returns false and logs Failed to show dialog for <player> when it cannot show the form. The usual causes are a Paper build without the Dialog API, which FormDialog.available() detects, or a repeated or blank input key, which throws while building.
A hologram appears twice
create was called while the original hologram's chunk was unloaded, so it was not found and a second one was spawned. Create holograms where the chunk is loaded. See Holograms.
Other servers do not react to a published message
Work down this list:
publishreturnsfalsewhen nobody is online on the sending server. That is expected.- The receiving server has nobody online, so the proxy skipped it.
- The channel string differs between a backend and the proxy relay. It must match exactly, in lower case.
bus.register()was never called.publishlogsMessageBus.publish called before register()in that case.- The proxy relay is not registered, or the proxy plugin is not installed.
- Two backends share a
server-id, so each ignores the other's messages as its own.
A migration fails every start after a partial failure
MySQL commits schema changes immediately, so a version with several DDL statements that failed part-way has left its earlier statements applied without recording the version. Undo the applied part by hand, or make the statements defensive with IF NOT EXISTS, then split the version into one DDL statement each. See SchemaMigrator.
Effects keep being drawn for players who left, or memory grows
Call renderLoop.remove(uuid) in a quit listener. The loop skips offline owners but does not unregister them. See Render Loop.
FAQ
Do I install StoneLib on my server?
No. It is shaded into each plugin that uses it. There is no StoneLib jar in plugins/.
Does it work on Spigot or Folia?
It is built against the Paper API and uses Paper-only features, such as Adventure components everywhere, TextDisplay holograms, and the Dialog API. It is not supported on Spigot. SchedulerService uses the classic Bukkit scheduler, which Folia does not provide.
Can I use just one module?
Yes. Nothing starts on its own and modules only depend on each other where noted on the Modules page. Unused classes cost nothing at runtime; to trim the jar, use the shade plugin's minimizeJar, and test the result, since it cannot see classes loaded by reflection.
Is the message bus reliable enough for economy transfers?
No. It is best-effort by design. Do the transfer in a database transaction, and use the bus only to tell other servers to refresh their cached balances.
Can I use MySqlRepository on a single server?
Yes. It is the better choice over SQLite for large data sets even on one server, because it writes only changed records.
Does CooldownService share cooldowns between servers?
No. Cooldowns are memory-only and per server. Persist expiry times yourself for anything that must follow a player across a network.