Skip to content

Commit

Permalink
Shadow netty rather than jar-in-jaring
Browse files Browse the repository at this point in the history
Under Forge, netty-codec lives on the BOOT layer. However, this means it
does not have access to our jzlib (which lives on the GAME layer). To
fix this, we now shadow netty-codec (and its dependents, like netty-http
and netty-proxy) rather than jar-in-jaring them.

This involves some horrible build logic, but means websocket compression
works on Forge.

Fixes #1958.
  • Loading branch information
SquidDev committed Sep 11, 2024
1 parent 52b76d8 commit 6b8ba8b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
5 changes: 4 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ librarian = "1.+"
lwjgl = "3.3.3"
minotaur = "2.+"
nullAway = "0.10.25"
shadow = "8.3.1"
spotless = "6.23.3"
taskTree = "2.1.1"
teavm = "0.11.0-SQUID.1"
Expand All @@ -94,9 +95,10 @@ jzlib = { module = "com.jcraft:jzlib", version.ref = "jzlib" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
kotlin-platform = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
netty-codec = { module = "io.netty:netty-codec", version.ref = "netty" }
netty-http = { module = "io.netty:netty-codec-http", version.ref = "netty" }
netty-socks = { module = "io.netty:netty-codec-socks", version.ref = "netty" }
netty-proxy = { module = "io.netty:netty-handler-proxy", version.ref = "netty" }
netty-socks = { module = "io.netty:netty-codec-socks", version.ref = "netty" }
nightConfig-core = { module = "com.electronwill.night-config:core", version.ref = "nightConfig" }
nightConfig-toml = { module = "com.electronwill.night-config:toml", version.ref = "nightConfig" }
slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
Expand Down Expand Up @@ -175,6 +177,7 @@ githubRelease = { id = "com.github.breadmoirai.github-release", version.ref = "g
gradleVersions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersions" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
librarian = { id = "org.parchmentmc.librarian.forgegradle", version.ref = "librarian" }
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
taskTree = { id = "com.dorongold.task-tree", version.ref = "taskTree" }
versionCatalogUpdate = { id = "nl.littlerobots.version-catalog-update", version.ref = "versionCatalogUpdate" }

Expand Down
20 changes: 20 additions & 0 deletions projects/core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import cc.tweaked.gradle.getAbsolutePath
plugins {
`java-library`
`java-test-fixtures`
alias(libs.plugins.shadow)

id("cc-tweaked.kotlin-convention")
id("cc-tweaked.java-convention")
Expand Down Expand Up @@ -57,3 +58,22 @@ val checkChangelog by tasks.registering(cc.tweaked.gradle.CheckChangelog::class)
}

tasks.check { dependsOn(checkChangelog) }

// We configure the shadow jar to ship netty-codec and all its dependencies, relocating them under the
// dan200.computercraft.core package.
// This is used as part of the Forge build, so that our version of netty-codec is loaded under the GAME layer, and so
// has access to our jar-in-jar'ed jzlib.
tasks.shadowJar {
minimize()

dependencies {
include(dependency(libs.netty.codec.get()))
include(dependency(libs.netty.http.get()))
include(dependency(libs.netty.socks.get()))
include(dependency(libs.netty.proxy.get()))
}

for (pkg in listOf("io.netty.handler.codec", "io.netty.handler.proxy")) {
relocate(pkg, "dan200.computercraft.core.vendor.$pkg")
}
}
31 changes: 18 additions & 13 deletions projects/forge/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ minecraft {
configurations {
minecraftLibrary { extendsFrom(minecraftEmbed.get()) }

// Move minecraftLibrary/minecraftEmbed out of implementation, and into runtimeOnly.
implementation { setExtendsFrom(extendsFrom - setOf(minecraftLibrary.get(), minecraftEmbed.get())) }
runtimeOnly { extendsFrom(minecraftLibrary.get(), minecraftEmbed.get()) }

val testMinecraftLibrary by registering {
isCanBeResolved = true
isCanBeConsumed = false
Expand Down Expand Up @@ -138,18 +142,11 @@ dependencies {
minecraftEmbed(libs.jzlib) {
jarJar.ranged(this, "[${libs.versions.jzlib.get()},)")
}
minecraftEmbed(libs.netty.http) {
jarJar.ranged(this, "[${libs.versions.netty.get()},)")
isTransitive = false
}
minecraftEmbed(libs.netty.socks) {
jarJar.ranged(this, "[${libs.versions.netty.get()},)")
isTransitive = false
}
minecraftEmbed(libs.netty.proxy) {
jarJar.ranged(this, "[${libs.versions.netty.get()},)")
isTransitive = false
}
// We don't jar-in-jar our additional netty dependencies (see the tasks.jarJar configuration), but still want them
// on the legacy classpath.
minecraftLibrary(libs.netty.http) { isTransitive = false }
minecraftLibrary(libs.netty.socks) { isTransitive = false }
minecraftLibrary(libs.netty.proxy) { isTransitive = false }

testFixturesApi(libs.bundles.test)
testFixturesApi(libs.bundles.kotlin)
Expand Down Expand Up @@ -195,9 +192,17 @@ tasks.sourcesJar {
tasks.jarJar {
finalizedBy("reobfJarJar")
archiveClassifier.set("")
duplicatesStrategy = DuplicatesStrategy.FAIL

// Include all classes from other projects except core.
val coreSources = project(":core").sourceSets["main"]
for (source in cct.sourceDirectories.get()) {
if (source.classes) from(source.sourceSet.output)
if (source.classes && source.sourceSet != coreSources) from(source.sourceSet.output)
}

// Include core separately, along with the relocated netty classes.
from(zipTree(project(":core").tasks.named("shadowJar", AbstractArchiveTask::class).map { it.archiveFile })) {
exclude("META-INF/**")
}
}

Expand Down

0 comments on commit 6b8ba8b

Please sign in to comment.