HomeJavaModsBileTools - Test Plugins Faster
BileTools - Test Plugins Faster
biletools-01.png
biletools-02.png
biletools-03.png
biletools-04.png
biletools-05.png
biletools-06.png
biletools-07.png
biletools-08.png
biletools-09.png
biletools-10.png
GITHUBDOCUMENTATIONDISCORD

Plain text version

Everything above, as readable text. Expand whichever section you need.

Spoiler: Overview - what BileTools does
BileTools watches your plugins directory and drives runtime lifecycle changes, so a rebuild lands in the running server instead of a restart.
  • Auto hot-reload. Recompile over an existing plugin jar and BileTools detects the content change automatically.
  • Hot-drop. Drop a new jar into the plugins directory and it is queued for runtime loading without a full restart.
  • Auto-unload. Delete a tracked jar and its plugin is unloaded.
  • Lifecycle commands. Load, unload, reload, install and uninstall by hand from the /bile command tree.
  • Dependency aware. Dependent plugins are unloaded and reloaded around a replacement instead of reloading one jar blindly.
  • Local plugin library. Every jar BileTools sees is archived by version, and the same folder is what /bile install reads from. Backup and rollback are the same feature.
  • Remote deploy. Push selected jar changes to other configured servers over an authenticated, size-limited, SHA-256 verified transfer.
Detection, in short: a size or timestamp change only wakes the watcher. A SHA-256 of the jar decides whether anything actually reloads, so a jar you touched but did not change is ignored.

BileTools is a development tool. It deliberately manipulates plugin lifecycle state at runtime. That is exactly what makes the development loop fast, and exactly why it belongs on dev and test servers. Hot reload is not a substitute for a clean restart on a live server.

Spoiler: Compatibility - runtimes and Java
One jar covers all six runtimes, Minecraft 1.20.1 through current 26.x.
  • Paper loads through the server's public PluginManager
  • Purpur same Paper-family load and unload paths
  • Leaf Paper-family fork, treated like Paper
  • Folia regionized scheduling, BileTools declares folia-supported
  • Canvas Folia fork, same regionized rules
  • Spigot loads through plugin.yml; jars that ship only paper-plugin.yml are refused
Java: Java 17 for Minecraft 1.20.1+, Java 25 for 26.x+. Match whatever your server already requires.

Folia and Canvas: hot reload on regionized servers is inherently more fragile. A third-party plugin that does not declare folia-support may still fail when hot-loaded.

Spoiler: Commands and permissions
Root command is /biletools. Aliases: /bile, /bi, /b.

Code (Text):
/bile load <plugin>                    Load a plugin jar from the plugins directory
/bile unload <plugin>                  Unload an installed plugin
/bile reload <plugin>                  Reload an installed plugin
/bile uninstall <plugin>               Delete a plugin jar from the plugins directory
/bile install <plugin> [version=..]    Install a plugin from the BileTools library
/bile library [plugin=..]              List library plugins, or versions for one plugin
One permission covers the whole tree:

Code (Text):
bile.use     Gives access to BileTools     default: op
Manual commands always bypass the watcher filters. Tab completion suggests installed plugins, library plugins and stored versions. Running /bile on its own opens a paginated hover-and-click help menu.

Optional arguments must be named. Passing them positionally fails with "unexpected argument":

Code (Text):
/bile install MyPlugin                   works  (defaults to version=latest)
/bile install MyPlugin version=1.4.2     works
/bile install MyPlugin version=latest    works
/bile install MyPlugin 1.4.2             FAILS

/bile library                            works  (lists everything)
/bile library plugin=MyPlugin            works
/bile library MyPlugin                   FAILS

Spoiler: Configuration - full default config.yml
Code (Text):
remote-deploy:
  slave:
    slave-enabled: false
    slave-port: 9876
    slave-payload: pickapassword
  master:
    master-enabled: false
    master-deploy-to:
    - yourserver.com:9876:password
    master-deploy-signatures:
    - MyPlugin
    - AnotherPlugin
  socket-timeout-ms: 15000
  max-transfer-bytes: 268435456
archive-plugins: true
watcher:
  idle-poll-ticks: 20
  active-poll-ticks: 5
  fingerprint-debounce-ticks: 8
  ignore:
  - LuckPerms
  - Vault
  - ProtocolLib
  - packetevents
  - WorldGuard
  - CoreProtect
  - spark
  only: []
  coalesce-window-ticks: 10
observability:
  log-timings: true
lifecycle:
  health-check: true
What each option does
  • watcher.ignore Plugin names that automatic hot-drop, reload and unload will skip. The defaults are things that are usually dangerous or useless to auto-reload on a dev box.
  • watcher.only When this list is not empty, only these plugins are auto-managed. Useful when you are actively developing one or two projects on a busy server.
  • watcher.active-poll-ticks / idle-poll-ticks How often the watcher scans while changes are arriving, versus once the directory has settled.
  • watcher.fingerprint-debounce-ticks How long a jar's fingerprint must hold steady before lifecycle work starts. This is what stops half-written jars from being loaded.
  • watcher.coalesce-window-ticks Batches nearby jar writes into one dependency-ordered reload flush, so a multi-module build does not trigger five separate reloads.
  • archive-plugins Archive each plugin jar into the library folder before it is replaced.
  • lifecycle.health-check After a load or reload, verify the plugin is actually registered and enabled. A failed operation marks the plugin dirty and pauses automatic reloads for it.
  • observability.log-timings Log per-phase timings (unload, dependents, load, health) for every operation.

Spoiler: Plugin library and rollback
Code (Text):
plugins/BileTools/library/<PluginName>/<version>.jar
With archive-plugins on, every plugin jar BileTools sees is copied here before it gets replaced. That means the library doubles as a rollback history, /bile library lists what you have, and /bile install <plugin> version=<version> puts any of it back into the running server.

Spoiler: Remote deploy
Optional. Lets a master server push selected jar changes to one or more slave servers.
  • On each receiving server: set remote-deploy.slave.slave-enabled: true, pick a port and set slave-payload to a shared password.
  • On the sending server: set remote-deploy.master.master-enabled: true, list each target in master-deploy-to in the form below, and list which plugins to forward in master-deploy-signatures.
Code (Text):
master-deploy-to:
- host:port:password
Transfers land in a temporary .part file and are only promoted after the password, filename, transfer size and SHA-256 all check out. Filenames are sanitized and any path that would escape the plugins folder is rejected. Defaults are a 256 MB cap and a 15 second socket timeout.

Spoiler: Languages - all 17 locale codes
English is selected by default. To switch, set locale in plugins/BileTools/language.yml:

Code (Text):
locale: en_US
Code (Text):
de_DE    German (Germany)
es_ES    Spanish (Spain)
fi_FI    Finnish (Finland)
fr_FR    French (France)
he_IL    Hebrew (Israel)
it_IT    Italian (Italy)
ja-JP    Japanese (Japan)
ko_KR    Korean (South Korea)
lt_LT    Lithuanian (Lithuania)
nl_NL    Dutch (Netherlands)
pl_PL    Polish (Poland)
pt_PT    Portuguese (Portugal)
ru_RU    Russian (Russia)
tr_TR    Turkish (Turkey)
vi_VI    Vietnamese (Vietnam)
zh_CN    Chinese (Simplified)
zh_TW    Chinese (Traditional)
You can also override individual lines without touching the bundles. Anything you add under a messages: section in language.yml wins; everything you leave out falls back to the selected language, then to English. The file is hot loaded upon save.

Spoiler: How a reload actually runs
Every operation hot-drop, reload, install, uninstall, remote deploy: goes through one serialized queue with dedupe keys, on a dedicated plugin-operations thread. Lifecycle mutations themselves always run on the global or main thread.

Code (Text):
detect -> stabilize -> fingerprint -> queue -> unload -> load -> dependents -> health check
Plugins that implement VolmLib's ReloadAware contract get a HOT_RELOAD or HOT_UNLOAD callback before their tasks are cancelled and listeners torn down, so they can drain in-flight work while their scheduler is still alive.

Unloading scrubs the plugin out of the live command graph, services, messaging channels and lookup tables before closing its classloader, which is why commands and tab-completion come back correct instead of half-wired.

Lifecycle waits carry an explicit timeout. A stuck operation surfaces as a failure and marks the plugin dirty rather than blocking the queue. Turn on observability.log-timings to see per-phase timings for every operation.

Spoiler: Known limits of hot reload
Not every plugin can be hot-reloaded cleanly, and BileTools does not pretend otherwise. Things that generally do not survive a class reload:
  • Static state fields held across a class reload
  • Background threads work started outside the plugin scheduler
  • Native resources anything bound outside the JVM
  • External connections sockets and pools with their own lifetime
  • Plugin-specific internals caches and registries other plugins own
Keep critical or obscure plugins in the ignore list, turn on timing logs while you iterate, and when the state cannot be safely reconstructed, restart the server.

Spoiler: Links

VOLMITSOFTWARE

Commands

Plugin details

Read from the plugin's own plugin.yml.

Quick facts

Install steps are the general flow for this file type — How to install Minecraft Java mods & modpacks walks through it step by step.

BileTools - Test Plugins Faster is a free Minecraft Java mod. Compatible with Minecraft 1.20, 1.20.6, 1.21, 26.1 and newer. Downloaded 2,727 times (via Spigot). Download it and open it directly in the game.

Explore more