JAR Hell
Warning
Some plugin developers improperly shade libraries which are already shipped with modern server versions without relocating them, breaking our plugin.
If you were sent here, try loading ChatControl WITHOUT ANY OTHER PLUGINS on your server. If it loads properly, add the plugins one-by-one until you find the culprit, then read this page and in most cases you'll need to contact the other developer to fix their bad coding practices.
Explainer for beginners
Your Minecraft server comes with many utility libraries. Some plugin developers use them in writing their plugins, however they include them in their plugin jar in a wrong way, causing conflicts.
For example, the Adventure library is shipped since Paper 1.16 in the server jar. Its Java package, the unique location, is net.kyori.adventure
.
Shading a library in a plugin's jar
When you're developing a plugin, there's no need to include Adventure if you only plan to support Paper 1.16. However, should you wish to support Spigot, or legacy Minecraft versions, you need to bundle the library in your jar.
Jar hell
Danger
If you bundle it as-is, meaning you don't relocate its package to for example me.myname.net.kyori.adventure
but leave it as net.kyori.adventure
, and the server already comes with the library with its original location of net.kyori.adventure
, bad things will happen, called "JAR hell".
The Java compiler will not be able to determine which version of the library it's being called should another plugin use it and cause conflicts. This is made worse by developers even shipping an outdated library in their plugin without relocation, which can crash ChatControl.
Here is an example of ChatControl loading with HexNicks plugin on legacy server version, this is how a crash will appear in the game console:
Upon decompiling HexNicks, we found it shaded an outdated Adventure library without relocation (the path net.kyori.adventure
should have been changed). Java compiler has thus given ChatControl the outdated library to use, leading to its crash:
Info
UPDATE: The issue appears to have been resolved in the most recent versions of HexNicks.
Here is an example of DiscordSRV, a well-made plugin shading the Adventure library in a relocated package, meaning ChatControl will properly use the official version of the library and Java knows that it should only serve DiscordSRV the library it ships with:
The solution is simple
Plugin developers need to configure their favorite tool like Maven or Gradle to relocate the library they shade into the plugin jar to be contained in a unique package, ideally prefixed with their own package name.
- Maven class relocation: https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
- Gradle task relocation: https://gradleup.com/shadow/configuration/relocation/