Skip to main content

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.yml bundled in your jar. New keys are merged from there on load.
  • The key name matches exactly, including case and nesting. menu.title means a title key inside a menu section.
  • A title's subtitle key exists. showTitle shows 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.

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:

  1. publish returns false when nobody is online on the sending server. That is expected.
  2. The receiving server has nobody online, so the proxy skipped it.
  3. The channel string differs between a backend and the proxy relay. It must match exactly, in lower case.
  4. bus.register() was never called. publish logs MessageBus.publish called before register() in that case.
  5. The proxy relay is not registered, or the proxy plugin is not installed.
  6. 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.