diff --git a/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java b/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java index 35af19dfcf..91ebb1a479 100644 --- a/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java +++ b/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java @@ -45,7 +45,10 @@ public class MySqlValidConnectionChecker extends ValidConnectionCheckerAdapter i public MySqlValidConnectionChecker(){ try { clazz = Utils.loadClass("com.mysql.jdbc.MySQLConnection"); - ping = clazz.getMethod("pingInternal", boolean.class, int.class); + if (clazz != null) { + ping = clazz.getMethod("pingInternal", boolean.class, int.class); + } + if (ping != null) { usePingMethod = true; } diff --git a/src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java b/src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java index a6e0cefbfd..28b42d2825 100644 --- a/src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java +++ b/src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java @@ -69,7 +69,7 @@ public class DruidXADataSource extends DruidDataSource implements XADataSource { } if (JdbcUtils.MYSQL.equals(dbType)) { - return MySqlUtils.createXAConnection(physicalConn); + return MySqlUtils.createXAConnection(driver, physicalConn); } if (JdbcUtils.POSTGRESQL.equals(dbType)) { diff --git a/src/main/java/com/alibaba/druid/util/MySqlUtils.java b/src/main/java/com/alibaba/druid/util/MySqlUtils.java index 1375b390c8..66e61376ea 100644 --- a/src/main/java/com/alibaba/druid/util/MySqlUtils.java +++ b/src/main/java/com/alibaba/druid/util/MySqlUtils.java @@ -15,28 +15,75 @@ */ package com.alibaba.druid.util; -import java.sql.Connection; -import java.sql.SQLException; - import javax.sql.XAConnection; - -import com.mysql.jdbc.Util; -import com.mysql.jdbc.jdbc2.optional.MysqlXAConnection; -import com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.Driver; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; public class MySqlUtils { + static Class utilClass; + static boolean utilClassError = false; + static boolean utilClass_isJdbc4 = false; - public static XAConnection createXAConnection(Connection physicalConn) throws SQLException { - com.mysql.jdbc.Connection mysqlConn = (com.mysql.jdbc.Connection)physicalConn; - if(mysqlConn.getPinGlobalTxToPhysicalConnection()) { + static Class connectionClass = null; + static Method getPinGlobalTxToPhysicalConnectionMethod = null; - if (!Util.isJdbc4()) { - return new SuspendableXAConnection(mysqlConn); - } + static Class suspendableXAConnectionClass = null; + static Constructor suspendableXAConnectionConstructor = null; - return new com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection(mysqlConn); - - } - return new MysqlXAConnection(mysqlConn, false); + static Class JDBC4SuspendableXAConnectionClass = null; + static Constructor JDBC4SuspendableXAConnectionConstructor = null; + + static Class MysqlXAConnectionClass = null; + static Constructor MysqlXAConnectionConstructor = null; + + public static XAConnection createXAConnection(Driver driver, Connection physicalConn) throws SQLException { + if (driver.getMajorVersion() == 5) { + if (utilClass == null && !utilClassError) { + try { + utilClass = Class.forName("com.mysql.jdbc.Util"); + + Method method = utilClass.getMethod("isJdbc4"); + utilClass_isJdbc4 = (Boolean) method.invoke(null); + + connectionClass = Class.forName("com.mysql.jdbc.Connection"); + getPinGlobalTxToPhysicalConnectionMethod = connectionClass.getMethod("getPinGlobalTxToPhysicalConnection"); + + suspendableXAConnectionClass = Class.forName("com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection"); + suspendableXAConnectionConstructor = suspendableXAConnectionClass.getConstructor(connectionClass); + + JDBC4SuspendableXAConnectionClass = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection"); + JDBC4SuspendableXAConnectionConstructor = JDBC4SuspendableXAConnectionClass.getConstructor(connectionClass); + + MysqlXAConnectionClass = Class.forName("com.mysql.jdbc.jdbc2.optional.MysqlXAConnection"); + MysqlXAConnectionConstructor = MysqlXAConnectionClass.getConstructor(connectionClass, boolean.class); + } catch (Exception ex) { + ex.printStackTrace(); + utilClassError = true; + } + } + + try { + boolean pinGlobTx = (Boolean) getPinGlobalTxToPhysicalConnectionMethod.invoke(physicalConn); + if (pinGlobTx) { + if (!utilClass_isJdbc4) { + return (XAConnection) suspendableXAConnectionConstructor.newInstance(physicalConn); + } + + return (XAConnection) JDBC4SuspendableXAConnectionConstructor.newInstance(physicalConn); + } + + return (XAConnection) MysqlXAConnectionConstructor.newInstance(physicalConn, Boolean.FALSE); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + throw new SQLFeatureNotSupportedException(); } } diff --git a/src/test/java/com/alibaba/druid/Bug_for_alibank.java b/src/test/java/com/alibaba/druid/Bug_for_alibank.java index 29decab51b..ba8054a6e2 100644 --- a/src/test/java/com/alibaba/druid/Bug_for_alibank.java +++ b/src/test/java/com/alibaba/druid/Bug_for_alibank.java @@ -26,5 +26,6 @@ public class Bug_for_alibank extends TestCase { System.out.println(jsonStrz); Object o = JSONUtils.parse(jsonStrz.replaceAll("\\\\", "")); System.out.println(JSONUtils.toJSONString(o)); + System.out.println(System.getProperty("java.vendor")); } } diff --git a/src/test/java/com/alibaba/druid/TestMySqlPing.java b/src/test/java/com/alibaba/druid/TestMySqlPing.java deleted file mode 100644 index a9cab0c827..0000000000 --- a/src/test/java/com/alibaba/druid/TestMySqlPing.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.druid; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; - -import com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker; - -import junit.framework.TestCase; - - -public class TestMySqlPing extends TestCase { - private String jdbcUrl; - private String user; - private String password; - private String driverClass; - - protected void setUp() throws Exception { - // jdbcUrl = "jdbc:oracle:thin:@a.b.c.d:1521:ocnauto"; - // user = "alibaba"; - // password = "ccbuauto"; - // SQL = "SELECT * FROM WP_ORDERS WHERE ID = ?"; - - jdbcUrl = "jdbc:mysql://a.b.c.d/tddl5_00"; - user = "aa"; - password = "bb"; - - driverClass = "com.mysql.jdbc.Driver"; - } - - public void test_o() throws Exception { - Class.forName(driverClass); - - Connection conn = DriverManager.getConnection(jdbcUrl, user, password); - - com.mysql.jdbc.Connection mysqlConn = (com.mysql.jdbc.Connection) conn; - - MySqlValidConnectionChecker checker = new MySqlValidConnectionChecker(); - - checker.isValidConnection(mysqlConn, "select 'x'", 30); - - for (int i = 0; i < 10; ++i) { - ping_1000(mysqlConn); - select_1000(mysqlConn); - } - - conn.close(); - } - - private void ping_1000(com.mysql.jdbc.Connection oracleConn) throws SQLException { - long startMillis = System.currentTimeMillis(); - final int COUNT = 10000; - for (int i = 0; i < COUNT; ++i) { - pring(oracleConn); - } - long millis = System.currentTimeMillis() - startMillis; - System.out.println("ping : " + millis); - } - - private void select_1000(com.mysql.jdbc.Connection oracleConn) throws SQLException { - long startMillis = System.currentTimeMillis(); - final int COUNT = 10000; - for (int i = 0; i < COUNT; ++i) { - select(oracleConn); - } - long millis = System.currentTimeMillis() - startMillis; - System.out.println("select : " + millis); - } - - public void pring(com.mysql.jdbc.Connection oracleConn) throws SQLException { - oracleConn.ping(); - } - - public void select(com.mysql.jdbc.Connection oracleConn) throws SQLException { - Statement stmt = oracleConn.createStatement(); - stmt.execute("SELECT 'x'"); - stmt.close(); - } -} diff --git a/src/test/java/com/alibaba/druid/TestMySqlPing2.java b/src/test/java/com/alibaba/druid/TestMySqlPing2.java deleted file mode 100644 index 1a0be3b4a7..0000000000 --- a/src/test/java/com/alibaba/druid/TestMySqlPing2.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.druid; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import junit.framework.TestCase; - -import com.alibaba.druid.pool.DruidDataSource; -import com.alibaba.druid.util.JdbcUtils; - -public class TestMySqlPing2 extends TestCase { - - private String jdbcUrl; - private String user; - private String password; - private String driverClass; - - private DruidDataSource dataSource; - - protected void setUp() throws Exception { - // jdbcUrl = "jdbc:oracle:thin:@a.b.c.d:1521:ocnauto"; - // user = "alibaba"; - // password = "ccbuauto"; - // SQL = "SELECT * FROM WP_ORDERS WHERE ID = ?"; - - jdbcUrl = "jdbc:mysql://a.b.c.d:3308/dragoon_v25_masterdb"; - user = "dragoon_admin"; - password = "dragoon_root"; - - driverClass = "com.mysql.jdbc.Driver"; - - dataSource = new DruidDataSource(); - dataSource.setUrl(jdbcUrl); - dataSource.setUsername(user); - dataSource.setPassword(password); - - dataSource.setMaxActive(4); - dataSource.setMinIdle(1); - dataSource.setTestOnBorrow(true); - } - - public void test_o() throws Exception { - { - Connection[] connections = new Connection[3]; - for (int i = 0; i < connections.length; ++i) { - connections[i] = dataSource.getConnection(); - } - - for (int i = 0; i < connections.length; ++i) { - Statement stmt = connections[i].createStatement(); - ResultSet rs = stmt.executeQuery("select now()"); - JdbcUtils.printResultSet(rs); - rs.close(); - stmt.close(); - } - - for (int i = 0; i < connections.length; ++i) { - connections[i].close(); - } - } - - - - - Thread.sleep(1000 * 60 * 60 * 6); // 6 hours - Connection conn = dataSource.getConnection(); - - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery("select now()"); - JdbcUtils.printResultSet(rs); - rs.close(); - stmt.close(); - - conn.close(); - } - - public void pring(com.mysql.jdbc.Connection oracleConn) throws SQLException { - oracleConn.ping(); - } - - public void select(com.mysql.jdbc.Connection oracleConn) throws SQLException { - Statement stmt = oracleConn.createStatement(); - stmt.execute("SELECT 'x'"); - stmt.close(); - } -} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidConnectionHolderTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidConnectionHolderTest.java index 6351d6f4ea..e707ed11f4 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DruidConnectionHolderTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidConnectionHolderTest.java @@ -1,40 +1,60 @@ package com.alibaba.druid.bvt.pool; -import java.sql.SQLException; - -import junit.framework.TestCase; - import com.alibaba.druid.filter.FilterAdapter; import com.alibaba.druid.filter.FilterChain; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; +import com.mysql.jdbc.Driver; +import junit.framework.TestCase; + +import java.sql.SQLException; public class DruidConnectionHolderTest extends TestCase { + Driver driver; private DruidDataSource dataSource; + private Class exceptionClass; + protected void setUp() throws Exception { - dataSource = new DruidDataSource(); - dataSource.setUrl("jdbc:mock:xxx"); - dataSource.setTestOnBorrow(false); - dataSource.setInitialSize(1); - dataSource.getProxyFilters().add(new FilterAdapter() { + driver = new Driver(); - public int connection_getTransactionIsolation(FilterChain chain, ConnectionProxy connection) - throws SQLException { - throw new com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException(); - } - }); + if (driver.getMajorVersion() == 5) { + exceptionClass = Class.forName("com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException"); + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setInitialSize(1); + dataSource.getProxyFilters().add(new FilterAdapter() { + + public int connection_getTransactionIsolation(FilterChain chain, ConnectionProxy connection) + throws SQLException { + throw createSyntaxException(); + } + }); + } + } + + protected SQLException createSyntaxException() { + try { + return (SQLException) exceptionClass.newInstance(); + } catch (Exception e) { + throw new IllegalStateException(); + } } protected void tearDown() throws Exception { - dataSource.close(); + if (dataSource != null) { + dataSource.close(); + } } public void test_mysqlSyntaxError() throws Exception { - dataSource.init(); - - dataSource.getConnection(); + if (driver.getMajorVersion() == 5) { + dataSource.init(); + + dataSource.getConnection(); + } } } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest.java b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest.java index 84f5397a40..76a32a09a3 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlExceptionSorterTest.java @@ -40,8 +40,10 @@ public class MySqlExceptionSorterTest extends TestCase { Assert.assertFalse(sorter.isExceptionFatal(new SQLException("", "", -8000))); } - public void test_true_3() throws Exception { - MySqlExceptionSorter sorter = new MySqlExceptionSorter(); - Assert.assertTrue(sorter.isExceptionFatal(new com.mysql.jdbc.CommunicationsException(null, 0, 0, null))); - } +// public void test_true_3() throws Exception { +// MySqlExceptionSorter sorter = new MySqlExceptionSorter(); +// Class clazz = Class.forName("new com.mysql.jdbc.CommunicationsException"); +// clazz.getConstructor() +// Assert.assertTrue(sorter.isExceptionFatal(new com.mysql.jdbc.CommunicationsException(null, 0, 0, null))); +// } } diff --git a/src/test/java/com/alibaba/druid/bvt/proxy/WrapImplTest.java b/src/test/java/com/alibaba/druid/bvt/proxy/WrapImplTest.java index ac98a8bedd..798ca61d02 100644 --- a/src/test/java/com/alibaba/druid/bvt/proxy/WrapImplTest.java +++ b/src/test/java/com/alibaba/druid/bvt/proxy/WrapImplTest.java @@ -27,6 +27,7 @@ import com.alibaba.druid.proxy.DruidDriver; import com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl; import com.alibaba.druid.proxy.jdbc.DataSourceProxyImpl; import com.alibaba.druid.stat.JdbcStatManager; +import com.alibaba.druid.util.Utils; public class WrapImplTest extends TestCase { @@ -57,7 +58,10 @@ public class WrapImplTest extends TestCase { Assert.assertEquals(10, dataSource.getRawDriverMajorVersion()); Assert.assertEquals(12, dataSource.getRawDriverMinorVersion()); - Assert.assertFalse(connection.isWrapperFor(com.mysql.jdbc.Connection.class)); + Class mysql5ConnectionClass = Utils.loadClass("com.mysql.jdbc.Connection"); + if (mysql5ConnectionClass != null) { + Assert.assertFalse(connection.isWrapperFor(mysql5ConnectionClass)); + } Assert.assertTrue(connection.isWrapperFor(ConnectionProxyImpl.class)); Assert.assertTrue(connection.isWrapperFor(org.apache.derby.impl.jdbc.EmbedConnection.class)); Assert.assertNotNull(connection.unwrap(ConnectionProxyImpl.class)); @@ -67,7 +71,9 @@ public class WrapImplTest extends TestCase { Assert.assertNotNull(derbyConnection); Statement statement = connection.createStatement(); - Assert.assertFalse(statement.isWrapperFor(com.mysql.jdbc.Statement.class)); + if (mysql5ConnectionClass != null) { + Assert.assertFalse(statement.isWrapperFor(Class.forName("com.mysql.jdbc.Statement"))); + } Assert.assertFalse(statement.isWrapperFor(null)); Assert.assertTrue(statement.isWrapperFor(org.apache.derby.impl.jdbc.EmbedStatement.class)); 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 82390e3688..0f4e2dae6d 100644 --- a/src/test/java/com/alibaba/druid/bvt/utils/MySqlUtilsTest.java +++ b/src/test/java/com/alibaba/druid/bvt/utils/MySqlUtilsTest.java @@ -1,17 +1,25 @@ package com.alibaba.druid.bvt.utils; -import java.lang.reflect.Constructor; - import com.alibaba.druid.util.MySqlUtils; -import com.mysql.jdbc.ConnectionImpl; - +import com.mysql.jdbc.Driver; import junit.framework.TestCase; +import java.lang.reflect.Constructor; +import java.sql.Connection; + public class MySqlUtilsTest extends TestCase { public void test_() throws Exception { - Constructor constructor = ConnectionImpl.class.getDeclaredConstructor(); - constructor.setAccessible(true); - ConnectionImpl conn = constructor.newInstance(); - MySqlUtils.createXAConnection(conn); + Driver driver = new Driver(); + int majorVersion = driver.getMajorVersion(); + + if (majorVersion == 5) { + Class clazz_ConnectionImpl = Class.forName("com.mysql.jdbc.ConnectionImpl"); + Constructor constructor = clazz_ConnectionImpl.getDeclaredConstructor(); + constructor.setAccessible(true); + Connection conn = (Connection) constructor.newInstance(); + MySqlUtils.createXAConnection(driver, conn); + } else if (majorVersion == 6) { + + } } } diff --git a/src/test/java/com/alibaba/druid/pool/TestMySqlPing.java b/src/test/java/com/alibaba/druid/pool/TestMySqlPing.java index 9e55f9c997..6af6aa172d 100644 --- a/src/test/java/com/alibaba/druid/pool/TestMySqlPing.java +++ b/src/test/java/com/alibaba/druid/pool/TestMySqlPing.java @@ -15,10 +15,13 @@ */ package com.alibaba.druid.pool; -import java.sql.DriverManager; - import junit.framework.TestCase; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverManager; + public class TestMySqlPing extends TestCase { public void test_ping() throws Exception { @@ -26,15 +29,16 @@ public class TestMySqlPing extends TestCase { String user = "dragoon_admin"; String password = "dragoon_root"; - Class.forName("com.mysql.jdbc.Driver"); + Driver driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance(); - com.mysql.jdbc.Connection conn = (com.mysql.jdbc.Connection) DriverManager.getConnection(url, user, password); + Connection conn = DriverManager.getConnection(url, user, password); ping(conn); conn.close(); } - public void ping(com.mysql.jdbc.Connection conn) throws Exception { + public void ping(Connection conn) throws Exception { System.out.println(conn.getClass()); - conn.ping(); + Method method = conn.getClass().getMethod("pring"); + method.invoke(conn); } } diff --git a/src/test/java/com/alibaba/druid/pool/mysql/MySqlTest.java b/src/test/java/com/alibaba/druid/pool/mysql/MySqlTest.java new file mode 100644 index 0000000000..ec33927336 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/mysql/MySqlTest.java @@ -0,0 +1,33 @@ +package com.alibaba.druid.pool.mysql; + +import com.alibaba.druid.pool.DruidDataSource; +import junit.framework.TestCase; + +import java.sql.Connection; + +/** + * Created by wenshao on 16/8/5. + */ +public class MySqlTest extends TestCase { + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mysql://100.69.167.129:3906/"); + dataSource.setUsername("pyson"); + dataSource.setPassword("pyson"); + dataSource.setFilters("log4j"); + dataSource.setValidationQuery("SELECT 1"); + dataSource.setTestOnBorrow(false); + dataSource.setTestWhileIdle(true); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_mysql() throws Exception { + Connection connection = dataSource.getConnection(); + connection.close(); + } +}