Skip to content

Commit ef84c17

Browse files
Use the shadow plugin to shade Jetty (#225)
* Use the shadow plugin to shade Jetty This allows clients that have not migrated onto Jetty 12 yet to use Tempest after the AWS DynamoDB Local upgrade Changes: * Upgrade gradle to v8.13 (required for shadow plugin) * Add the `tempest-dynamodb-local` subproject to manage the AWS DynamoDB Local dependency * Manually manage the transitive dependencies of AWS DynamoDB Local to prevent unexpected modules from being shaded * Use the shadow plugin to shade and relocate Kotlin Stdlib, Jetty, Jackson, and AWS DynamoDB Local * Fix publishing of artifacts to maven * Bump gradle-maven-publish-plugin to v0.28.0 * Hoist `dokkaGfm` outout directory setting outside of source sets loops to fix task dependencies in Gradle * Use a custom POM for `tempest-dynamodb-local` so that it use the shadow classpath when generating the runtime dependencies * Override the archive classifier on the unshaded jar to disambiguate the task output from the shadow jar * Use a package for shaded deps that is less likely to cause collisions
1 parent f8f94b6 commit ef84c17

File tree

10 files changed

+168
-40
lines changed

10 files changed

+168
-40
lines changed
File renamed without changes.

bin/gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
.gradle-7.6.1.pkg
1+
.gradle-8.13.pkg

build.gradle.kts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ buildscript {
1717
classpath(libs.junitGradlePlugin)
1818
classpath(libs.kotlinGradlePlugin)
1919
classpath(libs.mavenPublishGradlePlugin)
20+
classpath(libs.shadowGradlePlugin)
2021
classpath(libs.wireGradlePlugin)
2122
}
2223
}
@@ -100,26 +101,23 @@ subprojects {
100101
jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED")
101102
}
102103

103-
// We have to set the dokka configuration after evaluation since the com.vanniktech.maven.publish
104-
// plugin overwrites our dokka configuration on projects where it's applied.
105-
afterEvaluate {
106-
tasks.withType<DokkaTask>().configureEach {
107-
val dokkaTask = this
108-
dokkaSourceSets.configureEach {
109-
reportUndocumented.set(false)
110-
skipDeprecated.set(true)
111-
jdkVersion.set(11)
112-
113-
externalDocumentationLink {
114-
url.set(URL("https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/"))
115-
packageListUrl.set(
116-
URL("https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/package-list")
117-
)
118-
}
104+
tasks.withType<DokkaTask>().configureEach {
105+
val dokkaTask = this
119106

120-
if (dokkaTask.name == "dokkaGfm") {
121-
outputDirectory.set(project.file("$rootDir/docs/1.x"))
122-
}
107+
if (dokkaTask.name == "dokkaGfm") {
108+
outputDirectory.set(project.file("$rootDir/docs/1.x/${project.name}"))
109+
}
110+
111+
dokkaSourceSets.configureEach {
112+
reportUndocumented.set(false)
113+
skipDeprecated.set(true)
114+
jdkVersion.set(11)
115+
116+
externalDocumentationLink {
117+
url.set(URL("https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/"))
118+
packageListUrl.set(
119+
URL("https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/package-list")
120+
)
123121
}
124122
}
125123
}

gradle/libs.versions.toml

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
[versions]
2+
aws2 = "2.31.30"
3+
jackson = "2.14.3"
4+
jetty = "12.0.9"
25
ktlint = "0.40.0"
36
kotlin = "1.9.23"
7+
sqlite4java = "1.0.392"
48

59
[libraries]
10+
antlr4Runtime = { module = "org.antlr:antlr4-runtime", version = "4.13.2" }
611
assertj = { module = "org.assertj:assertj-core", version = "3.23.1" }
7-
aws2Dynamodb = { module = "software.amazon.awssdk:dynamodb", version = "2.25.11" }
8-
aws2DynamodbEnhanced = { module = "software.amazon.awssdk:dynamodb-enhanced", version = "2.25.11" }
9-
awsDynamodb = { module = "com.amazonaws:aws-java-sdk-dynamodb", version = "1.11.960" }
12+
aws2Dynamodb = { module = "software.amazon.awssdk:dynamodb", version.ref = "aws2" }
13+
aws2DynamodbEnhanced = { module = "software.amazon.awssdk:dynamodb-enhanced", version.ref = "aws2" }
14+
aws2Pinpoint = { module = "software.amazon.awssdk:pinpoint", version.ref = "aws2" } # for DynamoDBLocal
15+
awsDynamodb = { module = "com.amazonaws:aws-java-sdk-dynamodb", version = "1.12.782" }
1016
awsDynamodbLocal = { module = "com.amazonaws:DynamoDBLocal", version = "2.6.0" }
1117
clikt = { module = "com.github.ajalt:clikt", version = "2.8.0" }
18+
commonsCli = { module = "commons-cli:commons-cli", version = "1.9.0" } # for DynamoDBLocal
19+
commonsLang3 = { module = "org.apache.commons:commons-lang3", version = "3.17.0" } # for DynamoDBLocal
1220
dokkaGradlePlugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version = "1.9.20" }
1321
dockerCore = { module = "com.github.docker-java:docker-java-core", version = "3.2.13" }
1422
dockerTransport = { module = "com.github.docker-java:docker-java-transport-httpclient5", version = "3.2.13" }
1523
findbugsJsr305 = { module = "com.google.code.findbugs:jsr305", version = "3.0.2" }
1624
guava = { module = "com.google.guava:guava", version = "31.0.1-jre" }
25+
jacksonDatabind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } # for DynamoDBLocal
26+
jacksonDatatypeJsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } # for DynamoDBLocal
27+
jettyAlpnClient = { module = "org.eclipse.jetty:jetty-alpn-client", version.ref = "jetty" } # for DynamoDBLocal
28+
jettyClient = { module = "org.eclipse.jetty:jetty-client", version.ref = "jetty" } # for DynamoDBLocal
29+
jettyServer = { module = "org.eclipse.jetty:jetty-server", version.ref = "jetty" } # for DynamoDBLocal
1730
junit4Api = { module = "junit:junit", version = "4.13.2" }
1831
junitApi = { module = "org.junit.jupiter:junit-jupiter-api", version = "5.8.2" }
1932
junitEngine = { module = "org.junit.jupiter:junit-jupiter-engine", version = "5.11.4" }
@@ -26,10 +39,22 @@ kotlinxCoroutinesJdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk
2639
kotlinxCoroutinesReactive = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactive", version = "1.6.4" }
2740
log4jCore = { module = "org.apache.logging.log4j:log4j-core", version = "2.17.1" }
2841
loggingApi = { module = "io.github.microutils:kotlin-logging", version = "2.0.10" }
29-
mavenPublishGradlePlugin = { module = "com.vanniktech:gradle-maven-publish-plugin", version = "0.25.2" }
42+
mavenPublishGradlePlugin = { module = "com.vanniktech:gradle-maven-publish-plugin", version = "0.28.0" }
3043
moshiCore = { module = "com.squareup.moshi:moshi", version = "1.15.2" }
3144
moshiKotlin = { module = "com.squareup.moshi:moshi-kotlin", version = "1.15.2" }
3245
nettyBom = { module = "io.netty:netty-bom", version = "4.1.79.Final" }
3346
okio = { module = "com.squareup.okio:okio", version = "3.4.0" }
3447
okioFakefilesystem = { module = "com.squareup.okio:okio-fakefilesystem", version = "3.4.0" }
48+
shadowGradlePlugin = { module = "com.gradleup.shadow:shadow-gradle-plugin", version = "8.3.6" }
49+
slf4jApi = { module = "org.slf4j:slf4j-api", version = "2.0.17" } # for DynamoDBLocal
50+
sqlite4javaLinuxI386 = { module = "com.almworks.sqlite4java:libsqlite4java-linux-i386", version.ref = "sqlite4java" } # for DynamoDBLocal
51+
sqlite4javaLinuxAmd64 = { module = "com.almworks.sqlite4java:libsqlite4java-linux-amd64", version.ref = "sqlite4java" } # for DynamoDBLocal
52+
sqlite4javaOsx = { module = "com.almworks.sqlite4java:libsqlite4java-osx", version.ref = "sqlite4java" } # for DynamoDBLocal
53+
sqlite4javaWinX64 = { module = "com.almworks.sqlite4java:sqlite4java-win32-x64", version.ref = "sqlite4java" } # for DynamoDBLocal
54+
sqlite4javaWinX86 = { module = "com.almworks.sqlite4java:sqlite4java-win32-x86", version.ref = "sqlite4java" } # for DynamoDBLocal
3555
wireGradlePlugin = { module = "com.squareup.wire:wire-gradle-plugin", version = "4.8.1" }
56+
57+
[bundles]
58+
jackson = ["jacksonDatabind", "jacksonDatatypeJsr310"]
59+
jetty = ["jettyAlpnClient", "jettyClient", "jettyServer"]
60+
sqlite4java = ["sqlite4javaLinuxI386", "sqlite4javaLinuxAmd64", "sqlite4javaOsx", "sqlite4javaWinX64", "sqlite4javaWinX86"]

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ include("tempest-internal")
22
include("tempest")
33
include("tempest-bom")
44
include("tempest-docker")
5+
include("tempest-dynamodb-local")
56
include("tempest-testing")
67
include("tempest-testing-internal")
78
include("tempest-testing-docker")
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import com.vanniktech.maven.publish.JavadocJar.Dokka
2+
import com.vanniktech.maven.publish.KotlinJvm
3+
import com.vanniktech.maven.publish.MavenPublishBaseExtension
4+
5+
plugins {
6+
kotlin("jvm")
7+
`java-library`
8+
id("com.gradleup.shadow")
9+
id("com.vanniktech.maven.publish.base")
10+
}
11+
12+
dependencies {
13+
// Ignore transtive dependencies and instead manage explicitly.
14+
implementation(libs.awsDynamodbLocal) {
15+
isTransitive = false
16+
}
17+
18+
// Implementation dependencies will be shaded in the JAR.
19+
implementation(libs.bundles.jackson)
20+
implementation(libs.bundles.jetty)
21+
implementation(libs.kotlinStdLib)
22+
23+
// Shadow dependencies will not be shaded.
24+
shadow(libs.antlr4Runtime)
25+
shadow(libs.aws2Dynamodb)
26+
shadow(libs.aws2DynamodbEnhanced)
27+
shadow(libs.aws2Pinpoint)
28+
shadow(libs.awsDynamodb)
29+
shadow(libs.commonsCli)
30+
shadow(libs.commonsLang3)
31+
shadow(libs.guava)
32+
shadow(libs.slf4jApi)
33+
shadow(libs.bundles.sqlite4java)
34+
}
35+
36+
tasks.named<Jar>("jar") {
37+
archiveClassifier.set("unshaded")
38+
}
39+
40+
tasks.shadowJar {
41+
// Dependencies to be shaded must be explicitly included as dependencies.
42+
dependencies {
43+
include(dependency("com.amazonaws:DynamoDBLocal"))
44+
include(dependency("com.fasterxml.jackson.core:.*"))
45+
include(dependency("com.fasterxml.jackson.dataformat:.*"))
46+
include(dependency("com.fasterxml.jackson.datatype:.*"))
47+
include(dependency("com.fasterxml.jackson.module:.*"))
48+
include(dependency("org.eclipse.jetty:.*"))
49+
}
50+
51+
// Relocate packages to avoid conflicts.
52+
listOf(
53+
"com.amazon.dynamodb.grammar",
54+
"com.amazon.ion",
55+
"com.amazonaws.services.dynamodbv2.dataMembers",
56+
"com.amazonaws.services.dynamodbv2.datamodel",
57+
"com.amazonaws.services.dynamodbv2.dbenv",
58+
"com.amazonaws.services.dynamodbv2.exceptions",
59+
"com.amazonaws.services.dynamodbv2.local",
60+
"com.fasterxml.jackson",
61+
"ddb.partiql",
62+
"kotlin",
63+
"org.eclipse.jetty",
64+
"org.partiql",
65+
).forEach { relocate(it, "app.cash.tempest.testing.dynamodb.local.shaded.${it}") }
66+
67+
mergeServiceFiles()
68+
69+
// Publish shadow JAR as the main JAR.
70+
archiveClassifier = ""
71+
}
72+
73+
configure<MavenPublishBaseExtension> {
74+
configure(
75+
KotlinJvm(javadocJar = Dokka("dokkaGfm"))
76+
)
77+
78+
pom {
79+
withXml {
80+
val root = asNode()
81+
82+
// First collect all dependencies nodes.
83+
val dependenciesNodes = root.children()
84+
.filterIsInstance<groovy.util.Node>()
85+
.filter { it.name().toString().contains("dependencies") }
86+
.toList()
87+
88+
// Then remove them safely.
89+
dependenciesNodes.forEach { node ->
90+
root.remove(node)
91+
}
92+
93+
// Add a new dependencies node with shadow configuration.
94+
val dependenciesNode = root.appendNode("dependencies")
95+
96+
// Add all shadow dependencies to the POM.
97+
project.configurations.named("shadow").get().allDependencies.forEach { dep ->
98+
val dependencyNode = dependenciesNode.appendNode("dependency")
99+
dependencyNode.appendNode("groupId", dep.group)
100+
dependencyNode.appendNode("artifactId", dep.name)
101+
dependencyNode.appendNode("version", dep.version)
102+
dependencyNode.appendNode("scope", "compile")
103+
}
104+
}
105+
}
106+
}

tempest-testing-jvm/build.gradle.kts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import com.vanniktech.maven.publish.KotlinJvm
33
import com.vanniktech.maven.publish.MavenPublishBaseExtension
44

55
plugins {
6-
kotlin("jvm")
7-
`java-library`
6+
kotlin("jvm")
7+
`java-library`
88
id("com.vanniktech.maven.publish.base")
99
}
1010

1111
dependencies {
12-
api(project(":tempest-testing"))
13-
implementation(project(":tempest-testing-internal"))
14-
implementation(libs.awsDynamodbLocal)
15-
implementation(libs.kotlinStdLib)
12+
api(project(":tempest-testing"))
13+
implementation(project(":tempest-testing-internal"))
14+
implementation(project(path = ":tempest-dynamodb-local", configuration = "shadow"))
15+
implementation(libs.kotlinStdLib)
1616

17-
testImplementation(libs.assertj)
18-
testImplementation(libs.junitApi)
19-
testImplementation(libs.junitEngine)
17+
testImplementation(libs.assertj)
18+
testImplementation(libs.junitApi)
19+
testImplementation(libs.junitEngine)
2020
}
2121

2222

tempest-testing-jvm/src/main/kotlin/app/cash/tempest/testing/JvmDynamoDbServer.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
package app.cash.tempest.testing
1818

19-
import com.amazonaws.services.dynamodbv2.local.main.ServerRunner
20-
import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer
19+
import app.cash.tempest.testing.dynamodb.local.shaded.com.amazonaws.services.dynamodbv2.local.main.ServerRunner
20+
import app.cash.tempest.testing.dynamodb.local.shaded.com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer
2121
import com.google.common.util.concurrent.AbstractIdleService
22-
import java.io.File
2322

2423
class JvmDynamoDbServer private constructor(
2524
override val port: Int,

tempest2-testing-jvm/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
dependencies {
1212
api(project(":tempest2-testing"))
1313
implementation(project(":tempest2-testing-internal"))
14-
implementation(libs.awsDynamodbLocal)
14+
implementation(project(path = ":tempest-dynamodb-local", configuration = "shadow"))
1515
implementation(libs.kotlinStdLib)
1616

1717
testImplementation(libs.assertj)

tempest2-testing-jvm/src/main/kotlin/app/cash/tempest2/testing/JvmDynamoDbServer.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
package app.cash.tempest2.testing
1818

19-
import com.amazonaws.services.dynamodbv2.local.main.ServerRunner
20-
import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer
19+
import app.cash.tempest.testing.dynamodb.local.shaded.com.amazonaws.services.dynamodbv2.local.main.ServerRunner
20+
import app.cash.tempest.testing.dynamodb.local.shaded.com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer
2121
import com.google.common.util.concurrent.AbstractIdleService
22-
import java.io.File
2322

2423
class JvmDynamoDbServer private constructor(
2524
override val port: Int,

0 commit comments

Comments
 (0)