diff --git a/pom.xml b/pom.xml
index f932aff6a9..e73d8e0f76 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.alibaba
druid
- 1.1.6-SNAPSHOT
+ 1.1.6-preview_30
jar
druid
@@ -462,7 +462,7 @@
mysql
mysql-connector-java
- 5.1.41
+ 6.0.6
provided
diff --git a/src/main/java/com/alibaba/druid/util/MySqlUtils.java b/src/main/java/com/alibaba/druid/util/MySqlUtils.java
index d0df39aad2..59954a6462 100644
--- a/src/main/java/com/alibaba/druid/util/MySqlUtils.java
+++ b/src/main/java/com/alibaba/druid/util/MySqlUtils.java
@@ -17,7 +17,6 @@ package com.alibaba.druid.util;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
-import com.mysql.jdbc.ConnectionImpl;
import javax.sql.XAConnection;
import java.lang.reflect.Constructor;
@@ -30,21 +29,38 @@ import java.util.List;
import java.util.Set;
public class MySqlUtils {
- static Class> utilClass;
- static boolean utilClassError = false;
- static boolean utilClass_isJdbc4 = false;
+ static Class> utilClass;
+ static boolean utilClassError = false;
+ static boolean utilClass_isJdbc4 = false;
- static Class> connectionClass = null;
- static Method getPinGlobalTxToPhysicalConnectionMethod = null;
+ static Class> class_5_connection= null;
+ static Method method_5_getPinGlobalTxToPhysicalConnection = null;
+ static Class> class_5_suspendableXAConnection = null;
+ static Constructor> constructor_5_suspendableXAConnection = null;
+ static Class> class_5_JDBC4SuspendableXAConnection = null;
+ static Constructor> constructor_5_JDBC4SuspendableXAConnection = null;
+ static Class> class_5_MysqlXAConnection = null;
+ static Constructor> constructor_5_MysqlXAConnection = null;
- static Class> suspendableXAConnectionClass = null;
- static Constructor> suspendableXAConnectionConstructor = null;
+ static Class> class_5_ConnectionImpl = null;
+ static Method method_5_getId = null;
- static Class> JDBC4SuspendableXAConnectionClass = null;
- static Constructor> JDBC4SuspendableXAConnectionConstructor = null;
+ static Class> class_6_ConnectionImpl = null;
+ static Method method_6_getId = null;
+
+ volatile static Class> class_6_connection= null;
+ volatile static Method method_6_getPropertySet = null;
+ volatile static Method method_6_getBooleanReadableProperty = null;
+ volatile static Method method_6_getValue = null;
+ volatile static boolean method_6_getValue_error = false;
+
+ volatile static Class> class_6_suspendableXAConnection = null;
+ volatile static Method method_6_getInstance = null;
+ volatile static boolean method_6_getInstance_error = false;
+ volatile static Method method_6_getInstanceXA = null;
+ volatile static boolean method_6_getInstanceXA_error = false;
+ volatile static Class> class_6_JDBC4SuspendableXAConnection = null;
- static Class> MysqlXAConnectionClass = null;
- static Constructor> MysqlXAConnectionConstructor = null;
public static XAConnection createXAConnection(Driver driver, Connection physicalConn) throws SQLException {
final int major = driver.getMajorVersion();
@@ -56,17 +72,17 @@ public class MySqlUtils {
Method method = utilClass.getMethod("isJdbc4");
utilClass_isJdbc4 = (Boolean) method.invoke(null);
- connectionClass = Class.forName("com.mysql.jdbc.Connection");
- getPinGlobalTxToPhysicalConnectionMethod = connectionClass.getMethod("getPinGlobalTxToPhysicalConnection");
+ class_5_connection = Class.forName("com.mysql.jdbc.Connection");
+ method_5_getPinGlobalTxToPhysicalConnection = class_5_connection.getMethod("getPinGlobalTxToPhysicalConnection");
- suspendableXAConnectionClass = Class.forName("com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection");
- suspendableXAConnectionConstructor = suspendableXAConnectionClass.getConstructor(connectionClass);
+ class_5_suspendableXAConnection = Class.forName("com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection");
+ constructor_5_suspendableXAConnection = class_5_suspendableXAConnection.getConstructor(class_5_connection);
- JDBC4SuspendableXAConnectionClass = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection");
- JDBC4SuspendableXAConnectionConstructor = JDBC4SuspendableXAConnectionClass.getConstructor(connectionClass);
+ class_5_JDBC4SuspendableXAConnection = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection");
+ constructor_5_JDBC4SuspendableXAConnection = class_5_JDBC4SuspendableXAConnection.getConstructor(class_5_connection);
- MysqlXAConnectionClass = Class.forName("com.mysql.jdbc.jdbc2.optional.MysqlXAConnection");
- MysqlXAConnectionConstructor = MysqlXAConnectionClass.getConstructor(connectionClass, boolean.class);
+ class_5_MysqlXAConnection = Class.forName("com.mysql.jdbc.jdbc2.optional.MysqlXAConnection");
+ constructor_5_MysqlXAConnection = class_5_MysqlXAConnection.getConstructor(class_5_connection, boolean.class);
} catch (Exception ex) {
ex.printStackTrace();
utilClassError = true;
@@ -74,34 +90,118 @@ public class MySqlUtils {
}
try {
- boolean pinGlobTx = (Boolean) getPinGlobalTxToPhysicalConnectionMethod.invoke(physicalConn);
+ boolean pinGlobTx = (Boolean) method_5_getPinGlobalTxToPhysicalConnection.invoke(physicalConn);
if (pinGlobTx) {
if (!utilClass_isJdbc4) {
- return (XAConnection) suspendableXAConnectionConstructor.newInstance(physicalConn);
+ return (XAConnection) constructor_5_suspendableXAConnection.newInstance(physicalConn);
}
- return (XAConnection) JDBC4SuspendableXAConnectionConstructor.newInstance(physicalConn);
+ return (XAConnection) constructor_5_JDBC4SuspendableXAConnection.newInstance(physicalConn);
}
- return (XAConnection) MysqlXAConnectionConstructor.newInstance(physicalConn, Boolean.FALSE);
+ return (XAConnection) constructor_5_MysqlXAConnection.newInstance(physicalConn, Boolean.FALSE);
} catch (Exception e) {
e.printStackTrace();
}
+ } else if (major == 6) {
+ if (method_6_getValue == null && !method_6_getValue_error) {
+ try {
+ class_6_connection = Class.forName("com.mysql.cj.api.jdbc.JdbcConnection");
+ method_6_getPropertySet = class_6_connection.getMethod("getPropertySet");
+ method_6_getBooleanReadableProperty = Class.forName("com.mysql.cj.api.conf.PropertySet").getMethod("getBooleanReadableProperty", String.class);
+ method_6_getValue = Class.forName("com.mysql.cj.api.conf.ReadableProperty").getMethod("getValue");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ method_6_getValue_error = true;
+ }
+ }
+
+ try {
+ // pinGlobalTxToPhysicalConnection
+ boolean pinGlobTx = (Boolean) method_6_getValue.invoke(
+ method_6_getBooleanReadableProperty.invoke(
+ method_6_getPropertySet.invoke(physicalConn)
+ , "pinGlobalTxToPhysicalConnection"
+ )
+ );
+
+ if (pinGlobTx) {
+ try {
+ if (method_6_getInstance == null && !method_6_getInstance_error) {
+ class_6_suspendableXAConnection = Class.forName("com.mysql.cj.jdbc.SuspendableXAConnection");
+ method_6_getInstance = class_6_suspendableXAConnection.getDeclaredMethod("getInstance", class_6_connection);
+ method_6_getInstance.setAccessible(true);
+ }
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ method_6_getInstance_error = true;
+ }
+ return (XAConnection) method_6_getInstance.invoke(null, physicalConn);
+ } else {
+ try {
+ if (method_6_getInstanceXA == null && !method_6_getInstanceXA_error) {
+ class_6_JDBC4SuspendableXAConnection = Class.forName("com.mysql.cj.jdbc.MysqlXAConnection");
+ method_6_getInstanceXA = class_6_JDBC4SuspendableXAConnection.getDeclaredMethod("getInstance", class_6_connection, boolean.class);
+ method_6_getInstanceXA.setAccessible(true);
+ }
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ method_6_getInstanceXA_error = true;
+ }
+ return (XAConnection) method_6_getInstanceXA.invoke(null, physicalConn, Boolean.FALSE);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ method_6_getInstance_error = true;
+ }
}
throw new SQLFeatureNotSupportedException();
}
public static String buildKillQuerySql(Connection connection, SQLException error) throws SQLException {
+ Long threadId = null;
try {
- ConnectionImpl connImpl = (ConnectionImpl) connection;
- long threadId = connImpl.getId();
- return "KILL QUERY " + threadId;
+ Class clazz = connection.getClass();
+
+ if (class_5_ConnectionImpl == null) {
+ if (clazz.getName().equals("com.mysql.jdbc.ConnectionImpl")) {
+ class_5_ConnectionImpl = clazz;
+ }
+ }
+
+ if (class_5_ConnectionImpl == clazz) {
+ if (method_5_getId == null) {
+ method_5_getId = class_5_ConnectionImpl.getMethod("getId");
+ }
+
+ threadId = (Long) method_5_getId.invoke(connection);
+ }
+
+ if (class_6_ConnectionImpl == null) {
+ if (clazz.getName().equals("com.mysql.cj.jdbc.ConnectionImpl")) {
+ class_6_ConnectionImpl = clazz;
+ }
+ }
+
+ if (class_6_ConnectionImpl == clazz) {
+ if (method_6_getId == null) {
+ method_6_getId = class_6_ConnectionImpl.getMethod("getId");
+ }
+
+ threadId = (Long) method_6_getId.invoke(connection);
+ }
} catch (Exception e) {
// skip
}
- return null;
+
+ if (threadId == null) {
+ return null;
+ }
+
+ return "KILL QUERY " + threadId;
+
}
private static Set keywords;
@@ -308,4 +408,29 @@ public class MySqlUtils {
throw new SQLException("getLastPacketReceivedTimeMs error", e);
}
}
+
+ static Class> class_5_CommunicationsException = null;
+ static Class> class_6_CommunicationsException = null;
+
+ public static Class getCommunicationsExceptionClass() {
+ if (class_5_CommunicationsException != null) {
+ return class_5_CommunicationsException;
+ }
+
+ if (class_6_CommunicationsException != null) {
+ return class_6_CommunicationsException;
+ }
+
+ class_5_CommunicationsException = Utils.loadClass("com.mysql.jdbc.CommunicationsException");
+ if (class_5_CommunicationsException != null) {
+ return class_5_CommunicationsException;
+ }
+
+ class_6_CommunicationsException = Utils.loadClass("com.mysql.cj.jdbc.exceptions.CommunicationsException");
+ if (class_6_CommunicationsException != null) {
+ return class_6_CommunicationsException;
+ }
+
+ return null;
+ }
}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_1.java b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_1.java
index 649530df02..80218ea22e 100644
--- a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_1.java
+++ b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_1.java
@@ -2,9 +2,9 @@ package com.alibaba.druid.bvt.pool.vendor;
import com.alibaba.druid.PoolTestCase;
import com.alibaba.druid.pool.vendor.MySqlExceptionSorter;
-import com.mysql.jdbc.CommunicationsException;
-import junit.framework.TestCase;
+import com.alibaba.druid.util.MySqlUtils;
+import java.lang.reflect.Constructor;
import java.sql.SQLException;
/**
@@ -14,12 +14,40 @@ public class MySqlExceptionSorterTest_1 extends PoolTestCase {
public void test_0() throws Exception {
MySqlExceptionSorter sorter = new MySqlExceptionSorter();
- SQLException rootException = new SQLException(
- new SQLException("Could not retrieve transation read-only status server",
- new CommunicationsException(null, 0, 0, null)
- )
- );
+ Class clazz = MySqlUtils.getCommunicationsExceptionClass();
- assertTrue(sorter.isExceptionFatal(rootException));
+ if ("com.mysql.jdbc.CommunicationsException".equals(clazz.getName())) {
+ Constructor constructor = null;
+ for (Constructor item : clazz.getConstructors()) {
+ if (item.getParameterTypes().length == 4) {
+ constructor = item;
+ break;
+ }
+ }
+
+ SQLException rootException = new SQLException(
+ new SQLException("Could not retrieve transation read-only status server",
+ (Exception) constructor.newInstance(null, 0, 0, null)
+ )
+ );
+
+ assertTrue(sorter.isExceptionFatal(rootException));
+ } else {
+ Constructor constructor = null;
+ for (Constructor item : clazz.getConstructors()) {
+ if (item.getParameterTypes().length == 2) {
+ constructor = item;
+ break;
+ }
+ }
+
+ SQLException rootException = new SQLException(
+ new SQLException("Could not retrieve transation read-only status server",
+ (Exception) constructor.newInstance(null, null)
+ )
+ );
+
+ assertTrue(sorter.isExceptionFatal(rootException));
+ }
}
}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_2.java b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_2.java
index 1a830202fa..07316e08c8 100644
--- a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_2.java
+++ b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest_2.java
@@ -2,9 +2,10 @@ package com.alibaba.druid.bvt.pool.vendor;
import com.alibaba.druid.PoolTestCase;
import com.alibaba.druid.pool.vendor.MySqlExceptionSorter;
-import com.mysql.jdbc.CommunicationsException;
+import com.alibaba.druid.util.MySqlUtils;
import junit.framework.TestCase;
+import java.lang.reflect.Constructor;
import java.net.SocketTimeoutException;
import java.sql.SQLException;
diff --git a/src/test/java/com/alibaba/druid/bvt/proxy/DruidDriverTest.java b/src/test/java/com/alibaba/druid/bvt/proxy/DruidDriverTest.java
index f74636d98b..39695eaeef 100644
--- a/src/test/java/com/alibaba/druid/bvt/proxy/DruidDriverTest.java
+++ b/src/test/java/com/alibaba/druid/bvt/proxy/DruidDriverTest.java
@@ -76,7 +76,13 @@ public class DruidDriverTest extends TestCase {
}
public void test_getRawDriverClassName() throws Exception {
- Assert.assertEquals("com.mysql.jdbc.Driver", JdbcUtils.getDriverClassName("jdbc:mysql:"));
+ String className = JdbcUtils.getDriverClassName("jdbc:mysql:");
+ if (className.equals("com.mysql.jdbc.Driver")) {
+ assertEquals("com.mysql.jdbc.Driver", JdbcUtils.getDriverClassName("jdbc:mysql:"));
+ } else {
+ assertEquals("com.mysql.cj.jdbc.Driver", JdbcUtils.getDriverClassName("jdbc:mysql:"));
+ }
+
Assert.assertEquals("oracle.jdbc.OracleDriver", JdbcUtils.getDriverClassName("jdbc:oracle:"));
Assert.assertEquals("com.microsoft.jdbc.sqlserver.SQLServerDriver",
JdbcUtils.getDriverClassName("jdbc:microsoft:"));
diff --git a/src/test/java/com/alibaba/druid/bvt/utils/MySqlUtilsTest.java b/src/test/java/com/alibaba/druid/bvt/utils/MySqlUtilsTest.java
index 0f4e2dae6d..8062b4dfc2 100644
--- a/src/test/java/com/alibaba/druid/bvt/utils/MySqlUtilsTest.java
+++ b/src/test/java/com/alibaba/druid/bvt/utils/MySqlUtilsTest.java
@@ -19,7 +19,11 @@ public class MySqlUtilsTest extends TestCase {
Connection conn = (Connection) constructor.newInstance();
MySqlUtils.createXAConnection(driver, conn);
} else if (majorVersion == 6) {
-
+ Class> clazz_ConnectionImpl = Class.forName("com.mysql.cj.jdbc.ConnectionImpl");
+ Constructor> constructor = clazz_ConnectionImpl.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ Connection conn = (Connection) constructor.newInstance();
+ MySqlUtils.createXAConnection(driver, conn);
}
}
}