From a3766905a77226b49561a3b031c8df19bc55c7ab Mon Sep 17 00:00:00 2001
From: Brian Harrington <brharrington@gmail.com>
Date: Fri, 5 Nov 2021 19:25:40 -0500
Subject: [PATCH] shade jackson dependency for web-spring

This should help minimize issues with other uses that
might need to use older versions of jackson (e.g. #920).
---
 spectator-reg-atlas/build.gradle  |  4 +-
 spectator-web-spring/build.gradle | 83 ++++++++++++++++++++++++++++++-
 2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/spectator-reg-atlas/build.gradle b/spectator-reg-atlas/build.gradle
index 2781c640e..f7aa7c663 100644
--- a/spectator-reg-atlas/build.gradle
+++ b/spectator-reg-atlas/build.gradle
@@ -31,7 +31,7 @@ static boolean shouldBeShaded(String name) {
 }
 
 shadowJar {
-  classifier = null
+  archiveClassifier.set('')
   configurations = [project.configurations.runtimeClasspath]
   dependencies {
     exclude(dependency {
@@ -66,7 +66,7 @@ afterEvaluate {
 }
 
 
-// Sanity check the shadow jar to ensure something hasn't creeped in that is
+// Sanity check the shadow jar to ensure something hasn't crept in that is
 // not properly relocated.
 task checkShadowJar {
   doLast {
diff --git a/spectator-web-spring/build.gradle b/spectator-web-spring/build.gradle
index bc5588614..e62967cb8 100644
--- a/spectator-web-spring/build.gradle
+++ b/spectator-web-spring/build.gradle
@@ -13,19 +13,100 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+import java.util.zip.ZipFile
+
+plugins {
+  id 'com.github.johnrengelman.shadow' version '7.1.0'
+}
 
 dependencies {
   api project(':spectator-api')
   implementation 'org.springframework.boot:spring-boot-autoconfigure:2.5.6'
   implementation 'org.springframework:spring-beans:5.3.12'
   implementation 'org.springframework:spring-web:5.3.12'
-  api 'com.fasterxml.jackson.core:jackson-databind'
+  implementation 'com.fasterxml.jackson.core:jackson-databind'
 }
 
 jar {
+  // We only want to generate the shadow jar that hides the use of
+  // Jackson to prevent issues with other uses
+  enabled = false
   manifest {
     attributes(
       "Automatic-Module-Name": "com.netflix.spectator.spring"
     )
   }
 }
+
+jar.dependsOn("checkShadowJar")
+
+static boolean shouldBeShaded(String name) {
+  name.startsWith("jackson-")
+}
+
+shadowJar {
+  archiveClassifier.set('')
+  configurations = [project.configurations.runtimeClasspath]
+  dependencies {
+    exclude(dependency {
+      !shouldBeShaded(it.moduleName)
+    })
+  }
+  minimize()
+  exclude('module-info.class')
+  exclude('META-INF/versions/**')
+  exclude('META-INF/maven/com.fasterxml.jackson.*/**')
+  exclude('META-INF/services/com.fasterxml.*')
+  relocate('com.fasterxml.jackson', 'com.netflix.spectator.controllers.shaded.spectator-spring.json')
+}
+
+// Remove the Jackson dependencies from the POM file
+afterEvaluate {
+  publishing {
+    publications {
+      withType(MavenPublication) {
+        pom.withXml {
+          asNode()
+              .dependencies
+              .dependency
+              .findAll {
+                shouldBeShaded(it.artifactId.text())
+              }
+              .each { it.parent().remove(it) }
+        }
+      }
+    }
+  }
+}
+
+
+// Sanity check the shadow jar to ensure something hasn't crept in that is
+// not properly relocated.
+task checkShadowJar {
+  doLast {
+    configurations.archives.allArtifacts.forEach {
+      if (it.name == "spectator-web-spring" && it.extension == "jar") {
+        Set<String> metadataFiles = [
+            "META-INF/LICENSE",
+            "META-INF/MANIFEST.MF",
+            "META-INF/NOTICE",
+            "META-INF/spectator-web-spring.properties"
+        ]
+        ZipFile zf = new ZipFile(it.file)
+        try {
+          zf.stream()
+              .filter { !it.directory }
+              .filter { !it.name.startsWith("com/netflix/spectator/controllers/") }
+              .filter { !metadataFiles.contains(it.name) }
+              .forEach {
+                throw new IllegalStateException(
+                    "Unexpected file included in jar (${it.name}). Check shadow configuration.")
+              }
+        } finally {
+          zf.close()
+        }
+      }
+    }
+  }
+}
+checkShadowJar.dependsOn(shadowJar)