Shading is the concept of packing external dependencies inside your jar so that they exist in production.
Without this, using external libraries would produce ClassNotFoundException
s when you run your mod jar outside of an IDE.
This guide explains how to setup shading through Gradle.
This guide assumes that:
- You are on ForgeGradle 5 or higher
- You are on Gradle 7.0 or higher
Shading in Gradle is typically done through the use of the Gradle Shadow plugin.
First, set up the Shadow plugin by adding it to the plugins {}
block in your build.gradle
. If this block does not exist, add it above the apply plugin: 'net.minecraftforge.gradle'
line near the top of the file.
It should look something like this:
plugins {
// ... potentially other plugins ...
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
At the time of writing, 7.1.2 is the latest version of the Shadow plugin for Gradle 7. See the latest releases here. You should always try to stay up-to-date with releases of the Shadow plugin, so double check for yourself!
Next, add this block of code above the dependencies {}
block:
configurations {
shade
implementation.extendsFrom shade
}
dependencies {
// Dependencies here
}
This declares a new shade
configuration while also telling Gradle that dependencies under shade
should still be treated like normal in a development environment.
You must also configure the Shadow plugin to output the shaded jar correctly.
To prevent issues, you must ensure that the jar {}
block contains the line archiveClassifier = 'slim'
.
You should also configure the Shadow plugin after this jar {}
block:
jar {
archiveClassifier = 'slim'
manifest {
attributes([
// Attributes here
])
}
}
shadowJar {
archiveClassifier = ''
configurations = [project.configurations.shade]
finalizedBy 'reobfShadowJar'
}
assemble.dependsOn shadowJar
reobf {
shadowJar {}
}
With this setup, running gradlew build
will now produce two jars: a slim
variant and one without a classifier.
The no-classifier jar is now your shadowJar, which includes any dependencies you put into the shade
configuration.
Having a shaded jar isn't much use if you don't declare dependencies to be shaded.
To do this, add any repositories like normal to the repositories {}
block.
Then, you must make sure to add the external dependency to the shade
configuration.
Example:
dependencies {
minecraft 'net.minecraftforge:forge:<forge version>'
// ... Other dependencies ...
shade 'com.example:example-thing:1.0.0'
}
Additionally, you must also make sure to relocate any external packages to be under your own package.
This minimizes conflicts with other mods that may include the same dependencies as you!
This is an extra line that you must put inside of the shadowJar {}
block from earlier.
Example:
shadowJar {
archiveClassifier = ''
configurations = [project.configurations.shade]
relocate 'com.example.example-thing', "${project.group}.relocated.example-thing"
finalizedBy 'reobfShadowJar'
}
You should replace "com.example.example-thing" and "example-thing" with the package and name of the libraries you use.
Forge 1.17+ uses the module system, requiring a little more setup. See this guide on how to ensure that external libraries load in your IDE.
When I try shading the libraries I get the error
Modules <MyMod> and org.slf4j export package org.slf4j.event to module forge
. I am using Forge 1.20.1 so I assume that I would have to use theminecraftLibrary
configuration but then I cannot shade the dependencies anymore, right?I might be doing something else wrong though as the mod with shading has over 7 MB while it normally only has a couple hundred KB so I might be shading everything here.