Installation
StoneLib is a library, not a plugin. It never goes in a server's plugins/ folder. You depend on it at build time and shade it into your own plugin jar.
Requirements
| Requirement | Detail |
|---|---|
| Java | 25, to build and to run |
| Server software | Paper |
| Built against | io.papermc.paper:paper-api:26.2.build.123-stable |
| Build tool | Maven (Gradle works too, with the same coordinates) |
| Optional, at runtime | LuckPerms, for Permissions |
| Optional, at runtime | A MySQL driver, for MySQL |
| Optional, on a proxy | Velocity 3.4, for Cross-Server Messaging |
:::caution Java 25 is not optional
The current Paper release ships Java 25 class files. An older JDK cannot read paper-api at all, and the build fails with cannot access org.bukkit.* on every import. Use JDK 25 in your IDE, in CI, and on the server.
:::
Adding the dependency
From JitPack
The repository includes a jitpack.yml that pins OpenJDK 25, so JitPack can build it directly from a git tag or commit.
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.AnchorlightDev</groupId>
<artifactId>StoneLib</artifactId>
<version>TAG_OR_COMMIT</version>
</dependency>
</dependencies>
Replace TAG_OR_COMMIT with a release tag or a commit hash from the StoneLib repository. JitPack always uses com.github.<owner> as the group id, whatever the project's own pom.xml says.
From a local build
If you build StoneLib yourself (see Building from source), mvn install puts it in your local Maven repository under its own coordinates:
<dependency>
<groupId>dev.anchorlight</groupId>
<artifactId>StoneLib</artifactId>
<version>2.0.0</version>
</dependency>
The version is whatever pom.xml declares at the commit you built.
Pin Paper exactly
Declare paper-api yourself with provided scope, and pin an exact version:
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>26.2.build.123-stable</version>
<scope>provided</scope>
</dependency>
Paper versions carry a -stable qualifier, so a Maven range such as [26.2.build,) resolves to nothing.
Do not pin Adventure. paper-api manages it through adventure-bom, and an older pinned Adventure breaks the Dialog API, which needs a newer DialogLike.
What StoneLib brings with it
| Dependency | Scope in StoneLib | What it means for you |
|---|---|---|
paper-api | provided | Supplied by the server. Declare it yourself as above. |
boosted-yaml 1.3.7 | compile | Arrives transitively and is shaded into your jar. Used by config migration. Relocate it. |
HikariCP 6.2.1 | compile | Arrives transitively. Used by the MySQL connection pool. Relocate it. |
sqlite-jdbc 3.45.1.0 | compile | Arrives transitively. Only SqliteRepository needs it. Exclude it if you do not use SQLite, since it carries several megabytes of native libraries. |
mysql-connector-j 9.1.0 | provided | Not shaded. If you use the MySQL module, supply a driver at runtime. See below. |
LuckPerms api 5.4 | provided | Supplied by the LuckPerms plugin at runtime. Add LuckPerms as a softdepend if you use PermissionService. |
velocity-api 3.4.0-SNAPSHOT | provided, optional | Only needed by the Velocity side of the message bus. Absent on Paper, which is fine. |
Supplying the MySQL driver
The cleanest way is to let Paper download it once and share it between plugins, by listing it under libraries in plugin.yml:
libraries:
- com.mysql:mysql-connector-j:9.1.0
Excluding SQLite
<dependency>
<groupId>com.github.AnchorlightDev</groupId>
<artifactId>StoneLib</artifactId>
<version>TAG_OR_COMMIT</version>
<exclusions>
<exclusion>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
Shading and relocation
StoneLib has to travel inside your plugin jar. Relocate everything you bundle, so two plugins shading different StoneLib versions cannot collide on the same server:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>dev.anchorlight.stonelib</pattern>
<shadedPattern>com.example.myplugin.libs.stonelib</shadedPattern>
</relocation>
<relocation>
<pattern>dev.dejvokep.boostedyaml</pattern>
<shadedPattern>com.example.myplugin.libs.boostedyaml</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>com.example.myplugin.libs.hikari</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
:::caution Do not relocate what the server provides Paper, Adventure, LuckPerms, and Velocity classes must keep their real package names, or your plugin will not find them at runtime. Only relocate what you shade. :::
On a Velocity proxy
The proxy side of the message bus uses a single StoneLib class, ProxyMessageRelay. Velocity already provides Adventure, Guava, and SLF4J, so a proxy plugin should shade only StoneLib itself and leave everything else out of its jar.
Building from source
git clone https://github.com/AnchorlightDev/StoneLib.git
cd StoneLib
mvn clean package # compiles, runs the tests, builds the jar and a sources jar
mvn install # also installs it into your local Maven repository
The build produces a sources jar alongside the main one, so IDEs can show StoneLib's Javadoc and source when you step into it.
Tests run on JUnit 5 with MockBukkit and Mockito, and cover the command router, config manager and updater, holograms, message service and untrusted text, message encoding, the render loop, location encoding, both file repositories, and database config parsing.
Next steps
With the dependency in place, Getting Started shows how to wire the modules into a plugin.