This is an automated email from the ASF dual-hosted git repository.
jerryshao pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.3 by this push:
new 95a8e45966 [Cherry-pick to branch-1.3] [#12357] fix: Relocate Jackson
in Iceberg Aliyun bundle (#12358) (#12390)
95a8e45966 is described below
commit 95a8e45966a833fbffd8e3892665f486244acec0
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Aug 10 16:23:37 2026 +0800
[Cherry-pick to branch-1.3] [#12357] fix: Relocate Jackson in Iceberg
Aliyun bundle (#12358) (#12390)
**Cherry-pick Information:**
- Original commit: a2f687a85d4a057835340f658d02e0c1799dce54
- Target branch: `branch-1.3`
- Status: ✅ Clean cherry-pick (no conflicts)
Co-authored-by: roryqi <[email protected]>
Co-authored-by: Copilot Autofix powered by AI
<[email protected]>
---
bundles/iceberg-aliyun-bundle/build.gradle.kts | 30 ++++++++++
.../bundle/TestIcebergAliyunBundleShadowJar.java | 66 ++++++++++++++++++++++
2 files changed, 96 insertions(+)
diff --git a/bundles/iceberg-aliyun-bundle/build.gradle.kts
b/bundles/iceberg-aliyun-bundle/build.gradle.kts
index 829bf18bc0..cbe58b5cf3 100644
--- a/bundles/iceberg-aliyun-bundle/build.gradle.kts
+++ b/bundles/iceberg-aliyun-bundle/build.gradle.kts
@@ -32,10 +32,14 @@ dependencies {
implementation(libs.sun.activation)
// Include Gravitino Aliyun credential providers (OSSSecretKeyProvider,
etc.) for credential vending
implementation(project(":bundles:aliyun"))
+
+ testImplementation(libs.junit.jupiter.api)
+ testRuntimeOnly(libs.junit.jupiter.engine)
}
tasks.withType(ShadowJar::class.java) {
isZip64 = true
+ includeEmptyDirs = false
configurations = listOf(project.configurations.runtimeClasspath.get())
archiveClassifier.set("")
@@ -48,6 +52,20 @@ tasks.withType(ShadowJar::class.java) {
exclude(project(":catalogs:hadoop-common"))
}
+ // :bundles:aliyun pulls Jackson into this fat jar. Relocate it so the
bundle remains
+ // self-contained without exposing com.fasterxml.jackson classes on the
server classpath.
+ relocate(
+ "com.fasterxml.jackson",
+ "org.apache.gravitino.iceberg.aliyun.shaded.com.fasterxml.jackson"
+ )
+
+ // POM metadata is not relocated by shadow and would still advertise the
original
+ // Jackson coordinates.
+ exclude("META-INF/maven/com.fasterxml.jackson.core/**")
+ exclude("META-INF/maven/com.fasterxml.jackson.datatype/**")
+ exclude("META-INF/maven/com.fasterxml.jackson.module/**")
+ exclude("META-INF/maven/com.fasterxml.jackson/**")
+
mergeServiceFiles()
}
@@ -55,3 +73,15 @@ tasks.jar {
dependsOn(tasks.named("shadowJar"))
archiveClassifier.set("empty")
}
+
+tasks.test {
+ val shadowJar = tasks.named<ShadowJar>("shadowJar")
+ dependsOn(shadowJar)
+ inputs.file(shadowJar.flatMap { it.archiveFile })
+ doFirst {
+ systemProperty(
+ "shadowJarPath",
+ shadowJar.get().archiveFile.get().asFile.absolutePath
+ )
+ }
+}
diff --git
a/bundles/iceberg-aliyun-bundle/src/test/java/org/apache/gravitino/iceberg/bundle/TestIcebergAliyunBundleShadowJar.java
b/bundles/iceberg-aliyun-bundle/src/test/java/org/apache/gravitino/iceberg/bundle/TestIcebergAliyunBundleShadowJar.java
new file mode 100644
index 0000000000..a37da26a22
--- /dev/null
+++
b/bundles/iceberg-aliyun-bundle/src/test/java/org/apache/gravitino/iceberg/bundle/TestIcebergAliyunBundleShadowJar.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.iceberg.bundle;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+
+class TestIcebergAliyunBundleShadowJar {
+ private static final String RELOCATED_JACKSON_PREFIX =
+ "org/apache/gravitino/iceberg/aliyun/shaded/com/fasterxml/jackson/";
+
+ @Test
+ void jacksonShouldBeRelocated() throws IOException {
+ String jarPath = System.getProperty("shadowJarPath");
+ assertNotNull(jarPath, "shadowJarPath system property should be provided
by the build");
+
+ File shadowJar = new File(jarPath);
+ assertTrue(shadowJar.exists(), "shadow jar does not exist: " + shadowJar);
+
+ try (JarFile jarFile = new JarFile(shadowJar)) {
+ List<String> entries =
jarFile.stream().map(JarEntry::getName).collect(Collectors.toList());
+
+ assertTrue(
+ entries.stream().anyMatch(entry ->
entry.startsWith(RELOCATED_JACKSON_PREFIX)),
+ "Iceberg Aliyun bundle should keep Jackson under a relocated
namespace");
+ assertFalse(
+
entries.stream().anyMatch(TestIcebergAliyunBundleShadowJar::isUnshadedJacksonEntry),
+ "Iceberg Aliyun bundle should not expose unshaded Jackson classes or
services");
+ }
+ }
+
+ private static boolean isUnshadedJacksonEntry(String entry) {
+ if (entry.endsWith("/")) {
+ return false;
+ }
+ return entry.startsWith("com/fasterxml/jackson/")
+ || entry.matches("META-INF/versions/[^/]+/com/fasterxml/jackson/.*")
+ || entry.startsWith("META-INF/maven/com.fasterxml.jackson")
+ || entry.startsWith("META-INF/services/com.fasterxml.jackson");
+ }
+}