From ae3c550b4abbffbf5556e9cfcaa3ad540d7deecd Mon Sep 17 00:00:00 2001
From: Ziyu Shi <57038180+JackShi148@users.noreply.github.com>
Date: Fri, 15 Aug 2025 15:31:23 +0800
Subject: [PATCH 1/5] replace Fastjson with Jackson (#370)
---
pom.xml | 13 +++++--
.../alipay/oceanbase/rpc/ObTableClient.java | 35 ++++++++++++------
.../rpc/bolt/transport/ObTableConnection.java | 7 ++--
.../oceanbase/rpc/location/LocationUtil.java | 37 +++++++++++--------
.../rpc/location/model/OcpResponse.java | 10 +++++
.../rpc/location/model/OcpResponseData.java | 6 +++
.../location/model/OcpResponseDataIDC.java | 4 ++
.../rpc/location/model/OcpResponseDataRs.java | 5 +++
.../oceanbase/rpc/util/MonitorUtil.java | 30 ++++++++-------
.../oceanbase/rpc/ObTableClientInfoTest.java | 6 ++-
10 files changed, 103 insertions(+), 50 deletions(-)
diff --git a/pom.xml b/pom.xml
index 6167fc42..cac4d1f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,9 +112,9 @@
- com.alibaba
- fastjson
- 1.2.83
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.19.0
@@ -164,6 +164,10 @@
visible-assertions
org.rnorth.visible-assertions
+
+ jackson-annotations
+ com.fasterxml.jackson.core
+
@@ -388,7 +392,7 @@
maven-shade-plugin
- 3.2.4
+ 3.6.0
package
@@ -396,6 +400,7 @@
shade
+ false
true
shade
diff --git a/src/main/java/com/alipay/oceanbase/rpc/ObTableClient.java b/src/main/java/com/alipay/oceanbase/rpc/ObTableClient.java
index 805eaf39..e0f1e714 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/ObTableClient.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/ObTableClient.java
@@ -17,7 +17,6 @@
package com.alipay.oceanbase.rpc;
-import com.alibaba.fastjson.JSON;
import com.alipay.oceanbase.rpc.checkandmutate.CheckAndInsUp;
import com.alipay.oceanbase.rpc.constant.Constants;
import com.alipay.oceanbase.rpc.exception.*;
@@ -46,6 +45,9 @@
import com.alipay.oceanbase.rpc.threadlocal.ThreadLocalMap;
import com.alipay.oceanbase.rpc.util.*;
import com.alipay.remoting.util.StringUtils;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import java.util.*;
@@ -69,6 +71,15 @@
public class ObTableClient extends AbstractObTableClient implements Lifecycle {
private static final Logger logger = getLogger(ObTableClient.class);
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ static {
+ // FAIL_ON_EMPTY_BEANS means that whether throwing exception if there is no any serializable member with getter or setter in an object
+ // considering partitionElements in range partDesc is a list of Comparable interface and Comparable has no getter and setter
+ // we have to set this configuration as false because tableEntry may be serialized in debug log
+ objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+ }
+
private static final String usernameSeparators = ":;-;.";
private AtomicInteger tableEntryRefreshContinuousFailureCount = new AtomicInteger(
@@ -456,19 +467,19 @@ private void initMetadata() throws Exception {
List rsList = ocpModel.getObServerAddrs();
BOOT.info("{} success to get rsList, paramURL: {}, rsList: {},idc2Region: {}",
- this.database, paramURL, JSON.toJSON(rsList), JSON.toJSON(ocpModel.getIdc2Region()));
+ this.database, paramURL, objectMapper.writeValueAsString(rsList), objectMapper.writeValueAsString(ocpModel.getIdc2Region()));
TableEntry tableEntry = loadTableEntryRandomly(rsList,//
rootServerKey,//
tableEntryAcquireConnectTimeout,//
tableEntryAcquireSocketTimeout, sysUA, initialized);
BOOT.info("{} success to get tableEntry with rootServerKey all_dummy_tables {}",
- this.database, JSON.toJSON(tableEntry));
+ this.database, objectMapper.writeValueAsString(tableEntry));
List replicaLocations = tableEntry.getTableLocation()
.getReplicaLocations();
BOOT.info("{} success to get replicaLocation {}", this.database,
- JSON.toJSON(replicaLocations));
+ objectMapper.writeValueAsString(replicaLocations));
for (ReplicaLocation replicaLocation : replicaLocations) {
ObServerInfo info = replicaLocation.getInfo();
@@ -500,11 +511,11 @@ private void initMetadata() throws Exception {
}
if (servers.isEmpty()) {
BOOT.error("{} failed to connect any replicaLocation server: {}", this.database,
- JSON.toJSON(replicaLocations));
+ objectMapper.writeValueAsString(replicaLocations));
throw new Exception("failed to connect any replicaLocation server");
}
- BOOT.info("{} success to build server connection {}", this.database, JSON.toJSON(servers));
+ BOOT.info("{} success to build server connection {}", this.database, objectMapper.writeValueAsString(servers));
this.tableRoster = tableRoster;
this.serverRoster.reset(servers);
@@ -525,7 +536,7 @@ private void initMetadata() throws Exception {
if (BOOT.isInfoEnabled()) {
BOOT.info("{} finish refresh serverRoster: {}", this.database,
- JSON.toJSON(serverRoster));
+ objectMapper.writeValueAsString(serverRoster));
BOOT.info("finish initMetadata for all tables for database {}", this.database);
}
@@ -1031,7 +1042,7 @@ public void syncRefreshMetadata(boolean forceRenew) throws Exception {
currentIDC, regionFromOcp));
if (logger.isInfoEnabled()) {
- logger.info("finish refresh serverRoster: {}", JSON.toJSON(serverRoster));
+ logger.info("finish refresh serverRoster: {}", objectMapper.writeValueAsString(serverRoster));
}
this.lastRefreshMetadataTimestamp = System.currentTimeMillis();
} finally {
@@ -1365,7 +1376,8 @@ public TableEntry getOrRefreshTableEntry(final String tableName, final boolean r
* @throws ObTableEntryRefreshException
*/
private TableEntry refreshTableEntry(TableEntry tableEntry, String tableName)
- throws ObTableEntryRefreshException {
+ throws ObTableEntryRefreshException,
+ JsonProcessingException {
return refreshTableEntry(tableEntry, tableName, false);
}
@@ -1476,7 +1488,8 @@ public TableEntry refreshTableLocationByTabletId(TableEntry tableEntry, String t
* @throws ObTableEntryRefreshException
*/
private TableEntry refreshTableEntry(TableEntry tableEntry, String tableName, boolean fetchAll)
- throws ObTableEntryRefreshException {
+ throws ObTableEntryRefreshException,
+ JsonProcessingException {
TableEntryKey tableEntryKey = new TableEntryKey(clusterName, tenantName, database,
tableName);
try {
@@ -1552,7 +1565,7 @@ private TableEntry refreshTableEntry(TableEntry tableEntry, String tableName, bo
if (logger.isDebugEnabled()) {
logger.debug(
"refresh table entry, dataSource: {}, tableName: {}, refresh: {} key:{} entry:{} ",
- dataSourceName, tableName, true, tableEntryKey, JSON.toJSON(tableEntry));
+ dataSourceName, tableName, true, tableEntryKey, objectMapper.writeValueAsString(tableEntry));
}
return tableEntry;
}
diff --git a/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObTableConnection.java b/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObTableConnection.java
index eed5e608..79bf74d6 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObTableConnection.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/bolt/transport/ObTableConnection.java
@@ -17,7 +17,6 @@
package com.alipay.oceanbase.rpc.bolt.transport;
-import com.alibaba.fastjson.JSONObject;
import com.alipay.oceanbase.rpc.ObGlobal;
import com.alipay.oceanbase.rpc.exception.*;
import com.alipay.oceanbase.rpc.location.LocationUtil;
@@ -26,6 +25,7 @@
import com.alipay.oceanbase.rpc.table.ObTable;
import com.alipay.oceanbase.rpc.util.*;
import com.alipay.remoting.Connection;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import java.net.ConnectException;
@@ -40,6 +40,7 @@ public class ObTableConnection {
private static final Logger LOGGER = TableClientLoggerFactory
.getLogger(ObTableConnection.class);
+ private static ObjectMapper objectMapper = new ObjectMapper();
private ObBytesString credential;
private long tenantId = 1; //默认值切勿不要随意改动
private Connection connection;
@@ -153,8 +154,8 @@ private void login() throws Exception {
// When the caller doesn't provide any parameters, configsMap is empty.
// In this case, we don't generate any JSON to avoid creating an empty object.
if (loginWithConfigs && !obTable.getConfigs().isEmpty()) {
- JSONObject json = new JSONObject(obTable.getConfigs());
- request.setConfigsStr(json.toJSONString());
+ String configStr = objectMapper.writeValueAsString(obTable.getConfigs());
+ request.setConfigsStr(configStr);
loginWithConfigs = false;
}
generatePassSecret(request);
diff --git a/src/main/java/com/alipay/oceanbase/rpc/location/LocationUtil.java b/src/main/java/com/alipay/oceanbase/rpc/location/LocationUtil.java
index 05707387..57cdad23 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/location/LocationUtil.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/location/LocationUtil.java
@@ -17,10 +17,10 @@
package com.alipay.oceanbase.rpc.location;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONException;
-import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.parser.ParserConfig;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
import com.alipay.oceanbase.rpc.ObGlobal;
import com.alipay.oceanbase.rpc.constant.Constants;
import com.alipay.oceanbase.rpc.exception.*;
@@ -58,8 +58,13 @@ public class LocationUtil {
private static final Logger logger = TableClientLoggerFactory
.getLogger(LocationUtil.class);
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
static {
- ParserConfig.getGlobalInstance().setSafeMode(true);
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+ .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+ .enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
loadJdbcDriver();
}
@@ -774,7 +779,7 @@ private static TableEntry getTableEntryFromRemote(Connection connection, TableEn
if (!initialized) {
if (BOOT.isInfoEnabled()) {
- BOOT.info("get table entry from remote, entry={}", JSON.toJSON(tableEntry));
+ BOOT.info("get table entry from remote, entry={}", objectMapper.writeValueAsString(tableEntry));
}
} else {
if (logger.isInfoEnabled()) {
@@ -793,7 +798,7 @@ private static TableEntry getTableEntryFromRemote(Connection connection, TableEn
} catch (Exception e) {
RUNTIME.error(LCD.convert("01-00009"), key, e);
if (e instanceof ObTableEntryRefreshException) {
- throw e;
+ throw (ObTableEntryRefreshException) e;
}
throw new ObTableEntryRefreshException(format(
"fail to get table entry from remote, key=%s", key), e);
@@ -1113,7 +1118,7 @@ private static void fetchFirstPart(Connection connection, TableEntry tableEntry,
if (logger.isInfoEnabled()) {
logger.info(format("uuid:%s, get first ranges from remote for %s, bounds=%s",
- uuid, tableName, JSON.toJSON(bounds)));
+ uuid, tableName, objectMapper.writeValueAsString(bounds)));
}
} else if (obPartFuncType.isListPart()) {
@@ -1121,7 +1126,7 @@ private static void fetchFirstPart(Connection connection, TableEntry tableEntry,
((ObListPartDesc) tableEntry.getPartitionInfo().getFirstPartDesc()).setSets(sets);
if (logger.isInfoEnabled()) {
logger.info(format("uuid:%s, get first list sets from remote for %s, sets=%s",
- uuid, tableName, JSON.toJSON(sets)));
+ uuid, tableName, objectMapper.writeValueAsString(sets)));
}
} else if (ObGlobal.obVsnMajor() >= 4
&& (obPartFuncType.isKeyPart() || obPartFuncType.isHashPart())) {
@@ -1186,14 +1191,14 @@ private static void fetchSubPart(Connection connection, TableEntry tableEntry,
.setHighBoundValues(highBoundVals);
if (logger.isInfoEnabled()) {
logger.info(format("uuid:%s, get sub ranges from remote for %s, bounds=%s",
- uuid, tableName, JSON.toJSON(bounds)));
+ uuid, tableName, objectMapper.writeValueAsString(bounds)));
}
} else if (subPartFuncType.isListPart()) {
Map sets = parseSubPartSets(rs, tableEntry);
((ObListPartDesc) tableEntry.getPartitionInfo().getSubPartDesc()).setSets(sets);
if (logger.isInfoEnabled()) {
logger.info(format("uuid:%s, get sub list sets from remote, sets=%s", uuid,
- JSON.toJSON(sets)));
+ objectMapper.writeValueAsString(sets)));
}
} else if (ObGlobal.obVsnMajor() >= 4
&& (subPartFuncType.isKeyPart() || subPartFuncType.isHashPart())) {
@@ -1499,7 +1504,7 @@ private static void fetchPartitionInfo(Connection connection, TableEntry tableEn
info = parsePartitionInfo(rs);
if (logger.isInfoEnabled()) {
- logger.info("get part info from remote info:{}", JSON.toJSON(info));
+ logger.info("get part info from remote info:{}", objectMapper.writeValueAsString(info));
}
tableEntry.setPartitionInfo(info);
} catch (SQLException e) {
@@ -2085,7 +2090,7 @@ private static OcpResponse getRemoteOcpResponseOrNull(String paramURL, String da
for (; tries < tryTimes; tries++) {
try {
content = loadStringFromUrl(paramURL, connectTimeout, readTimeout);
- ocpResponse = JSONObject.parseObject(content, OcpResponse.class);
+ ocpResponse = objectMapper.readValue(content, OcpResponse.class);
if (ocpResponse != null && ocpResponse.validate()) {
if (dataSourceName != null && !dataSourceName.isEmpty()) {
saveLocalContent(dataSourceName, content);
@@ -2132,7 +2137,7 @@ private static OcpResponse getRemoteOcpIdcRegionOrNull(String paramURL, int conn
for (; tries < tryTimes; tries++) {
try {
content = loadStringFromUrl(paramURL, connectTimeout, readTimeout);
- ocpResponse = JSONObject.parseObject(content, OcpResponse.class);
+ ocpResponse = objectMapper.readValue(content, OcpResponse.class);
if (ocpResponse != null) {
return ocpResponse;
}
@@ -2150,8 +2155,8 @@ private static OcpResponse getRemoteOcpIdcRegionOrNull(String paramURL, int conn
return null;
}
- private static OcpResponse parseOcpResponse(String content) throws JSONException {
- return JSONObject.parseObject(content, OcpResponse.class);
+ private static OcpResponse parseOcpResponse(String content) throws JsonProcessingException {
+ return objectMapper.readValue(content, OcpResponse.class);
}
private static OcpResponse getLocalOcpResponseOrNull(String fileName) {
diff --git a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponse.java b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponse.java
index fa20c1ba..ce0b8d20 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponse.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponse.java
@@ -17,6 +17,8 @@
package com.alipay.oceanbase.rpc.location.model;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
public class OcpResponse {
private int Code;
private String Message;
@@ -26,6 +28,7 @@ public class OcpResponse {
/*
* Get code.
*/
+ @JsonProperty("Code")
public int getCode() {
return Code;
}
@@ -40,6 +43,7 @@ public void setCode(int code) {
/*
* Get message.
*/
+ @JsonProperty("Message")
public String getMessage() {
return Message;
}
@@ -58,6 +62,11 @@ public boolean isSuccess() {
return Success;
}
+ @JsonProperty("Success")
+ public boolean getSuccess() {
+ return Success;
+ }
+
/*
* Set success.
*/
@@ -68,6 +77,7 @@ public void setSuccess(boolean success) {
/*
* Get data.
*/
+ @JsonProperty("Data")
public OcpResponseData getData() {
return Data;
}
diff --git a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseData.java b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseData.java
index e647b998..34d767c6 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseData.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseData.java
@@ -17,6 +17,8 @@
package com.alipay.oceanbase.rpc.location.model;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
import java.util.List;
public class OcpResponseData {
@@ -28,6 +30,7 @@ public class OcpResponseData {
/*
* Get ob region.
*/
+ @JsonProperty("ObRegion")
public String getObRegion() {
return ObRegion;
}
@@ -42,6 +45,7 @@ public void setObRegion(String obRegion) {
/*
* Get ob region id.
*/
+ @JsonProperty("ObRegionId")
public long getObRegionId() {
return ObRegionId;
}
@@ -56,6 +60,7 @@ public void setObRegionId(long obRegionId) {
/*
* Get rs list.
*/
+ @JsonProperty("RsList")
public List getRsList() {
return RsList;
}
@@ -70,6 +75,7 @@ public void setRsList(List rsList) {
/*
* Get IDC list.
*/
+ @JsonProperty("IDCList")
public List getIDCList() {
return IDCList;
}
diff --git a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataIDC.java b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataIDC.java
index bba403cc..ab51ec3b 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataIDC.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataIDC.java
@@ -17,6 +17,8 @@
package com.alipay.oceanbase.rpc.location.model;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
/*
* Idc->Region mapping defined in OCP.
*
@@ -29,6 +31,7 @@ public class OcpResponseDataIDC {
/*
* Get idc.
*/
+ @JsonProperty("idc")
public String getIdc() {
return idc;
}
@@ -43,6 +46,7 @@ public void setIdc(String idc) {
/*
* Get region.
*/
+ @JsonProperty("region")
public String getRegion() {
return region;
}
diff --git a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataRs.java b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataRs.java
index 43d8bf00..691a90e8 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataRs.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/location/model/OcpResponseDataRs.java
@@ -17,6 +17,8 @@
package com.alipay.oceanbase.rpc.location.model;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
public class OcpResponseDataRs {
private String address;
private String role;
@@ -25,6 +27,7 @@ public class OcpResponseDataRs {
/*
* Get address.
*/
+ @JsonProperty("address")
public String getAddress() {
return address;
}
@@ -39,6 +42,7 @@ public void setAddress(String address) {
/*
* Get role.
*/
+ @JsonProperty("role")
public String getRole() {
return role;
}
@@ -53,6 +57,7 @@ public void setRole(String role) {
/*
* Get sql_port.
*/
+ @JsonProperty("sql_port")
public int getSql_port() {
return sql_port;
}
diff --git a/src/main/java/com/alipay/oceanbase/rpc/util/MonitorUtil.java b/src/main/java/com/alipay/oceanbase/rpc/util/MonitorUtil.java
index a0a01692..8e806306 100644
--- a/src/main/java/com/alipay/oceanbase/rpc/util/MonitorUtil.java
+++ b/src/main/java/com/alipay/oceanbase/rpc/util/MonitorUtil.java
@@ -17,7 +17,6 @@
package com.alipay.oceanbase.rpc.util;
-import com.alibaba.fastjson.JSON;
import com.alipay.oceanbase.rpc.protocol.payload.ResultCodes;
import com.alipay.oceanbase.rpc.protocol.payload.impl.ObObj;
import com.alipay.oceanbase.rpc.protocol.payload.impl.ObRowKey;
@@ -29,6 +28,8 @@
import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.query.ObTableQuery;
import com.alipay.oceanbase.rpc.stream.ObTableClientQueryStreamResult;
import com.alipay.oceanbase.rpc.table.AbstractTableQuery;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.Arrays;
@@ -38,10 +39,11 @@
import static com.alipay.oceanbase.rpc.util.TraceUtil.formatTraceMessage;
public class MonitorUtil {
- private static String buildParamsString(List