diff --git a/CHANGES.md b/CHANGES.md
index cd3bcd3e177a..f9f29c3aa906 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -91,6 +91,7 @@
* Python SDK: Legacy runner support removed from Dataflow, all pipelines must use runner v2.
* [Python] Dataflow Runner will no longer stage Beam SDK from PyPI in the `--staging_location` at pipeline submission. Custom container images that are not based on Beam's default image must include Apache Beam installation.([#26996](https://github.com/apache/beam/issues/26996))
+* SDK Java Extensions SQL: remove fastjson library, table property is changed to ObjectNode which belongs to jackson library. ([#24154](https://github.com/apache/beam/issues/24154))
## Deprecations
diff --git a/playground/backend/containers/java/Dockerfile b/playground/backend/containers/java/Dockerfile
index 3688c435080d..f9d1b24b96d2 100644
--- a/playground/backend/containers/java/Dockerfile
+++ b/playground/backend/containers/java/Dockerfile
@@ -65,7 +65,6 @@ ENV BEAM_SDK="SDK_JAVA"
ENV PROPERTY_PATH=/opt/playground/backend/properties.yaml
ARG CALCITE_VERSION=1_28_0
ARG BYTEBUDDY_VERSION=1.12.14
-ARG FASTJSON_VERSION=1.2.69
ARG JANINO_VERSION=3.0.11
# Copy build result
@@ -103,9 +102,6 @@ RUN wget https://repo1.maven.org/maven2/org/apache/beam/beam-vendor-calcite-$CAL
RUN wget https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy/$BYTEBUDDY_VERSION/byte-buddy-$BYTEBUDDY_VERSION.jar &&\
mv byte-buddy-$BYTEBUDDY_VERSION.jar /opt/apache/beam/jars/byte-buddy-$BYTEBUDDY_VERSION.jar
-RUN wget https://repo1.maven.org/maven2/com/alibaba/fastjson/$FASTJSON_VERSION/fastjson-$FASTJSON_VERSION.jar &&\
- mv fastjson-$FASTJSON_VERSION.jar /opt/apache/beam/jars/fastjson-$FASTJSON_VERSION.jar
-
RUN wget https://repo1.maven.org/maven2/org/codehaus/janino/janino/$JANINO_VERSION/janino-$JANINO_VERSION.jar &&\
mv janino-$JANINO_VERSION.jar /opt/apache/beam/jars/janino-$JANINO_VERSION.jar
diff --git a/sdks/java/extensions/sql/build.gradle b/sdks/java/extensions/sql/build.gradle
index 01b87ddcfd81..8a22bff69b7f 100644
--- a/sdks/java/extensions/sql/build.gradle
+++ b/sdks/java/extensions/sql/build.gradle
@@ -84,7 +84,6 @@ dependencies {
implementation library.java.jackson_databind
implementation library.java.joda_time
implementation library.java.vendored_calcite_1_28_0
- implementation "com.alibaba:fastjson:1.2.69"
implementation "org.codehaus.janino:janino:3.0.11"
implementation "org.codehaus.janino:commons-compiler:3.0.11"
implementation library.java.jackson_core
diff --git a/sdks/java/extensions/sql/datacatalog/build.gradle b/sdks/java/extensions/sql/datacatalog/build.gradle
index e4508d28d141..cb557cc80776 100644
--- a/sdks/java/extensions/sql/datacatalog/build.gradle
+++ b/sdks/java/extensions/sql/datacatalog/build.gradle
@@ -34,7 +34,7 @@ dependencies {
implementation library.java.protobuf_java
implementation library.java.slf4j_api
implementation library.java.vendored_guava_32_1_2_jre
- implementation "com.alibaba:fastjson:1.2.69"
+ implementation library.java.jackson_databind
implementation project(path: ":sdks:java:core", configuration: "shadow")
implementation "org.threeten:threetenbp:1.4.5"
provided project(":sdks:java:extensions:sql")
diff --git a/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/BigQueryTableFactory.java b/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/BigQueryTableFactory.java
index e799875f88e3..172dad752d93 100644
--- a/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/BigQueryTableFactory.java
+++ b/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/BigQueryTableFactory.java
@@ -17,14 +17,13 @@
*/
package org.apache.beam.sdk.extensions.sql.meta.provider.datacatalog;
-import com.alibaba.fastjson.JSONObject;
import com.google.cloud.datacatalog.v1beta1.Entry;
import java.net.URI;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.beam.sdk.extensions.sql.TableUtils;
import org.apache.beam.sdk.extensions.sql.meta.Table;
-import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.collect.ImmutableMap;
/** {@link TableFactory} that understands Data Catalog BigQuery entries. */
class BigQueryTableFactory implements TableFactory {
@@ -49,7 +48,7 @@ public Optional
tableBuilder(Entry entry) {
return Optional.of(
Table.builder()
.location(getLocation(entry))
- .properties(new JSONObject(ImmutableMap.of("truncateTimestamps", truncateTimestamps)))
+ .properties(TableUtils.emptyProperties().put("truncateTimestamps", truncateTimestamps))
.type("bigquery")
.comment(""));
}
diff --git a/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/GcsTableFactory.java b/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/GcsTableFactory.java
index 39d963af2a80..3a85362bbeab 100644
--- a/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/GcsTableFactory.java
+++ b/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/GcsTableFactory.java
@@ -17,11 +17,11 @@
*/
package org.apache.beam.sdk.extensions.sql.meta.provider.datacatalog;
-import com.alibaba.fastjson.JSONObject;
import com.google.cloud.datacatalog.v1beta1.Entry;
import com.google.cloud.datacatalog.v1beta1.GcsFilesetSpec;
import java.util.List;
import java.util.Optional;
+import org.apache.beam.sdk.extensions.sql.TableUtils;
import org.apache.beam.sdk.extensions.sql.meta.Table;
/** {@link TableFactory} that understands Data Catalog GCS entries. */
@@ -55,7 +55,7 @@ public Optional tableBuilder(Entry entry) {
Table.builder()
.type("text")
.location(filePattern)
- .properties(new JSONObject())
+ .properties(TableUtils.emptyProperties())
.comment(""));
}
}
diff --git a/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/PubsubTableFactory.java b/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/PubsubTableFactory.java
index 656f4dd2202f..5688713f7ee8 100644
--- a/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/PubsubTableFactory.java
+++ b/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/PubsubTableFactory.java
@@ -17,12 +17,12 @@
*/
package org.apache.beam.sdk.extensions.sql.meta.provider.datacatalog;
-import com.alibaba.fastjson.JSONObject;
import com.google.cloud.datacatalog.v1beta1.Entry;
import java.net.URI;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.beam.sdk.extensions.sql.TableUtils;
import org.apache.beam.sdk.extensions.sql.meta.Table;
/** {@link TableFactory} that understands Data Catalog Pubsub entries. */
@@ -42,7 +42,7 @@ public Optional tableBuilder(Entry entry) {
return Optional.of(
Table.builder()
.location(getLocation(entry))
- .properties(new JSONObject())
+ .properties(TableUtils.emptyProperties())
.type("pubsub")
.comment(""));
}
diff --git a/sdks/java/extensions/sql/hcatalog/build.gradle b/sdks/java/extensions/sql/hcatalog/build.gradle
index d7dc94467ff9..e8abf21b7c3e 100644
--- a/sdks/java/extensions/sql/hcatalog/build.gradle
+++ b/sdks/java/extensions/sql/hcatalog/build.gradle
@@ -41,7 +41,6 @@ dependencies {
implementation project(":sdks:java:extensions:sql")
implementation project(":sdks:java:io:hcatalog")
implementation project(":sdks:java:core")
- implementation "com.alibaba:fastjson:1.2.69"
implementation library.java.vendored_guava_32_1_2_jre
testImplementation project(":sdks:java:io:hcatalog").sourceSets.test.output
diff --git a/sdks/java/extensions/sql/hcatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/hcatalog/DatabaseProvider.java b/sdks/java/extensions/sql/hcatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/hcatalog/DatabaseProvider.java
index 90adeaf85f23..925cca4bcabb 100644
--- a/sdks/java/extensions/sql/hcatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/hcatalog/DatabaseProvider.java
+++ b/sdks/java/extensions/sql/hcatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/hcatalog/DatabaseProvider.java
@@ -17,7 +17,6 @@
*/
package org.apache.beam.sdk.extensions.sql.meta.provider.hcatalog;
-import com.alibaba.fastjson.JSONObject;
import java.util.Map;
import org.apache.beam.sdk.extensions.sql.meta.BeamSqlTable;
import org.apache.beam.sdk.extensions.sql.meta.Table;
@@ -80,7 +79,6 @@ public Map getTables() {
.schema(tableSchema.get())
.name(table)
.location("")
- .properties(new JSONObject())
.comment("")
.type("hcatalog")
.build();
diff --git a/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/TableUtils.java b/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/TableUtils.java
new file mode 100644
index 000000000000..2e52a1bbf422
--- /dev/null
+++ b/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/TableUtils.java
@@ -0,0 +1,69 @@
+/*
+ * 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.beam.sdk.extensions.sql;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.json.JsonReadFeature;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.Map;
+import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.annotations.VisibleForTesting;
+
+public class TableUtils {
+ private static final ObjectMapper objectMapper =
+ JsonMapper.builder()
+ .enable(
+ JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER,
+ JsonReadFeature.ALLOW_JAVA_COMMENTS,
+ JsonReadFeature.ALLOW_MISSING_VALUES,
+ JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS,
+ JsonReadFeature.ALLOW_LEADING_ZEROS_FOR_NUMBERS,
+ JsonReadFeature.ALLOW_SINGLE_QUOTES,
+ JsonReadFeature.ALLOW_TRAILING_COMMA,
+ JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS,
+ JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES)
+ .build();
+
+ private TableUtils() {
+ // nothing here
+ }
+
+ @VisibleForTesting
+ public static ObjectMapper getObjectMapper() {
+ return objectMapper;
+ }
+
+ public static ObjectNode emptyProperties() {
+ return objectMapper.createObjectNode();
+ }
+
+ public static ObjectNode parseProperties(String json) {
+ try {
+ return (ObjectNode) objectMapper.readTree(json);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("illegal table properties: " + json);
+ }
+ }
+
+ public static Map convertNode2Map(JsonNode jsonNode) {
+ return objectMapper.convertValue(jsonNode, new TypeReference