Randint
Randint

Reputation: 73

[Forge 1.8.9]: Including dependencies in JAR

I've been making a Forge mod for Minecraft 1.8.9 with the Forge MDK. So far my mod has 1 dependency, which is SnakeYAML. I added this line: compile 'org.yaml:snakeyaml:1.30' to my build.gradle file, so that I have SnakeYAML during development, but it doesn't get included when I build the JAR. Is there any way to include SnakeYAML in my JAR as well?

Upvotes: 2

Views: 1392

Answers (2)

Holly Cummins
Holly Cummins

Reputation: 11492

Forge recommend shading dependencies into a fat jar, and they have a set of instructions: https://github.com/MinecraftForge/ForgeGradle/blob/FG_1.2/docs/user-guide/shading.md.

I preferred not to use shading, for two reasons:

  • Shading doesn’t include transitive dependencies
  • By definition, shading renames packages. That can help avoid conflicts on the classpath, but he rename of packages can cause problems for libraries that use reflection.

I did a simple fat-package, rather than shading. I bundled everything on the runtime classpath into the jar, but excluded the minecraft dependency category. The minecraft dependencies are going to be available on the server, and if there is more than one copy, the runtime throws exceptions.


jar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    from {
        configurations.runtimeClasspath.findAll { file ->
            // Exclude the transitive dependencies of minecraft dependency type, which should not go into the fat jar
            // when true, jar file is unzipped and added
            !configurations.minecraft.contains(file)
        }.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

The inclusion of the extra libraries has to happen in the jar task itself, not something like a fatJar task. The reason is that what gets installed into a server needs to the the output of gradle build, not just gradle jar or gradle fatJar. Otherwise the built jar doesn't go through the proper cycle of obfuscation and deobfuscation and reobfuscation, which causes java.lang.NoSuchMethodError against the Minecraft API itself.

Upvotes: 0

Lucan
Lucan

Reputation: 3595

You can create a fat Jar. In summary, a fat Jar contains all of the dependency classes and resources in a single output Jar. I assume you're using Gradle as this is a Forge project.

Add the Shadow plugin

plugins {
  id 'com.github.johnrengelman.shadow' version '7.1.2'
  id 'java'
}

Then configure your dependencies to shadow in SnakeYAML:

dependencies {
  implementation 'org.yaml:snakeyaml:1.30'
  ...
  shadow 'org.yaml:snakeyaml:1.30'
}

Finally, use the ShadowJar task added under 'Shadow' to build your fat Jar. You may need to change the version of Shadow for the gradle version you're using. Refer to the documentation for any configuration you may wish to add.

Upvotes: 1

Related Questions