From e00395ecd975acdf92c08ae9b65024c89ce080d1 Mon Sep 17 00:00:00 2001 From: lyl2008dsg Date: Sun, 18 Aug 2024 19:50:07 +0800 Subject: [PATCH 1/3] bugfix: Resolve MySQL Driver Loading Issue (#6760) --- .../store/db/AbstractDataSourceProvider.java | 70 +------------------ distribution/NOTICE.md | 4 +- 2 files changed, 5 insertions(+), 69 deletions(-) diff --git a/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java b/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java index 2287fcd3b85..d73e5cdbd1b 100644 --- a/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java +++ b/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java @@ -16,17 +16,6 @@ */ package org.apache.seata.core.store.db; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Stream; - -import javax.sql.DataSource; - import org.apache.seata.common.exception.StoreException; import org.apache.seata.common.executor.Initialize; import org.apache.seata.common.util.ConfigTools; @@ -38,6 +27,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.sql.DataSource; + import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MAX_CONN; import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MIN_CONN; @@ -56,20 +47,8 @@ public abstract class AbstractDataSourceProvider implements DataSourceProvider, */ protected static final Configuration CONFIG = ConfigurationFactory.getInstance(); - private final static String MYSQL_DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver"; - - private final static String MYSQL8_DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver"; - - private final static String MYSQL_DRIVER_FILE_PREFIX = "mysql-connector-java-"; - - private final static Map MYSQL_DRIVER_LOADERS; - private static final long DEFAULT_DB_MAX_WAIT = 5000; - static { - MYSQL_DRIVER_LOADERS = createMysqlDriverClassLoaders(); - } - @Override public void init() { this.dataSource = generate(); @@ -145,50 +124,7 @@ protected Long getMaxWait() { } protected ClassLoader getDriverClassLoader() { - return MYSQL_DRIVER_LOADERS.getOrDefault(getDriverClassName(), ClassLoader.getSystemClassLoader()); - } - - private static Map createMysqlDriverClassLoaders() { - Map loaders = new HashMap<>(); - String cp = System.getProperty("java.class.path"); - if (cp == null || cp.isEmpty()) { - return loaders; - } - Stream.of(cp.split(File.pathSeparator)) - .map(File::new) - .filter(File::exists) - .map(file -> file.isFile() ? file.getParentFile() : file) - .filter(Objects::nonNull) - .filter(File::isDirectory) - .map(file -> new File(file, "jdbc")) - .filter(File::exists) - .filter(File::isDirectory) - .distinct() - .flatMap(file -> { - File[] files = file.listFiles((f, name) -> name.startsWith(MYSQL_DRIVER_FILE_PREFIX)); - if (files != null) { - return Stream.of(files); - } else { - return Stream.of(); - } - }) - .forEach(file -> { - if (loaders.containsKey(MYSQL8_DRIVER_CLASS_NAME) && loaders.containsKey(MYSQL_DRIVER_CLASS_NAME)) { - return; - } - try { - URL url = file.toURI().toURL(); - ClassLoader loader = new URLClassLoader(new URL[]{url}, ClassLoader.getSystemClassLoader()); - try { - loader.loadClass(MYSQL8_DRIVER_CLASS_NAME); - loaders.putIfAbsent(MYSQL8_DRIVER_CLASS_NAME, loader); - } catch (ClassNotFoundException e) { - loaders.putIfAbsent(MYSQL_DRIVER_CLASS_NAME, loader); - } - } catch (MalformedURLException ignore) { - } - }); - return loaders; + return ClassLoader.getSystemClassLoader(); } /** diff --git a/distribution/NOTICE.md b/distribution/NOTICE.md index 2d1e571afad..ad620bf4765 100644 --- a/distribution/NOTICE.md +++ b/distribution/NOTICE.md @@ -273,8 +273,8 @@ Please copy database driver dependencies, such as `mysql-connector-java.jar`, to ├── spring-web-5.3.30.jar ├── spring-webmvc-5.3.30.jar ├── xstream-1.4.20.jar + ├── mysql-connector-java-8.0.28.jar └── jdbc - ├── mysql-connector-java-8.0.28.jar └── NOTICE.md ``` @@ -555,8 +555,8 @@ Please copy database driver dependencies, such as `mysql-connector-java.jar`, to ├── spring-web-5.3.30.jar ├── spring-webmvc-5.3.30.jar ├── xstream-1.4.20.jar + ├── mysql-connector-java-8.0.28.jar └── jdbc - ├── mysql-connector-java-8.0.28.jar └── NOTICE.md ``` \ No newline at end of file From 17d909ea518d4d940a77999220b7c8fe070ada04 Mon Sep 17 00:00:00 2001 From: lyl2008dsg Date: Sat, 24 Aug 2024 16:06:51 +0800 Subject: [PATCH 2/3] add ut --- .../seata/core/store/db/AbstractDataSourceProvider.java | 4 ++-- distribution/NOTICE.md | 4 ++-- .../server/store/db/AbstractDataSourceProviderTest.java | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java b/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java index d73e5cdbd1b..9cca970ea69 100644 --- a/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java +++ b/core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java @@ -16,6 +16,8 @@ */ package org.apache.seata.core.store.db; +import javax.sql.DataSource; + import org.apache.seata.common.exception.StoreException; import org.apache.seata.common.executor.Initialize; import org.apache.seata.common.util.ConfigTools; @@ -27,8 +29,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.sql.DataSource; - import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MAX_CONN; import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MIN_CONN; diff --git a/distribution/NOTICE.md b/distribution/NOTICE.md index ad620bf4765..2d1e571afad 100644 --- a/distribution/NOTICE.md +++ b/distribution/NOTICE.md @@ -273,8 +273,8 @@ Please copy database driver dependencies, such as `mysql-connector-java.jar`, to ├── spring-web-5.3.30.jar ├── spring-webmvc-5.3.30.jar ├── xstream-1.4.20.jar - ├── mysql-connector-java-8.0.28.jar └── jdbc + ├── mysql-connector-java-8.0.28.jar └── NOTICE.md ``` @@ -555,8 +555,8 @@ Please copy database driver dependencies, such as `mysql-connector-java.jar`, to ├── spring-web-5.3.30.jar ├── spring-webmvc-5.3.30.jar ├── xstream-1.4.20.jar - ├── mysql-connector-java-8.0.28.jar └── jdbc + ├── mysql-connector-java-8.0.28.jar └── NOTICE.md ``` \ No newline at end of file diff --git a/server/src/test/java/org/apache/seata/server/store/db/AbstractDataSourceProviderTest.java b/server/src/test/java/org/apache/seata/server/store/db/AbstractDataSourceProviderTest.java index 1b29b15c4e3..a0d8c9f8fe9 100644 --- a/server/src/test/java/org/apache/seata/server/store/db/AbstractDataSourceProviderTest.java +++ b/server/src/test/java/org/apache/seata/server/store/db/AbstractDataSourceProviderTest.java @@ -35,6 +35,8 @@ public class AbstractDataSourceProviderTest { private final String hikariDatasourceType = "hikari"; + private final String mysqlJdbcDriver = "com.mysql.jdbc.Driver"; + @Test public void testDbcpDataSourceProvider() { DataSource dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbcpDatasourceType).provide(); @@ -52,4 +54,11 @@ public void testHikariDataSourceProvider() { DataSource dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, hikariDatasourceType).provide(); Assertions.assertNotNull(dataSource); } + + @Test + public void testMySQLDataSourceProvider() throws ClassNotFoundException { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + Class driverClass = Class.forName(mysqlJdbcDriver, true, classLoader); + Assertions.assertNotNull(driverClass); + } } From 236692b4891629cad2aeb4ab5820aa05490845a6 Mon Sep 17 00:00:00 2001 From: lyl2008dsg Date: Sat, 24 Aug 2024 16:29:49 +0800 Subject: [PATCH 3/3] add change --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 8e3433ad9fe..cb25d12f580 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -25,6 +25,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6701](https://github.com/apache/incubator-seata/pull/6728)] fix support serialization for dm.jdbc.driver.DmdbTimestamp - [[#6757](https://github.com/apache/incubator-seata/pull/6757)] the bug where multiple nodes cannot be retrieved from the naming server - [[#6769](https://github.com/apache/incubator-seata/pull/6769)] fix tcc fence deadLock +- [[#6765](https://github.com/apache/incubator-seata/pull/6765)] fix MySQL driver loading by replacing custom classloader with system classloader for better compatibility and simplified process ### optimize: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 3594e35e1c0..952583c1c97 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -26,6 +26,8 @@ - [[#6701](https://github.com/apache/incubator-seata/pull/6728)] 修复达梦数据库的对dm.jdbc.driver.DmdbTimestamp的支持 - [[#6757](https://github.com/apache/incubator-seata/pull/6757)] 修复client通过namingserver只能获取到一个tc节点的bug - [[#6769](https://github.com/apache/incubator-seata/pull/6769)] 修复tcc fence死锁 +- [[#6765](https://github.com/apache/incubator-seata/pull/6765)] 改进MySQL驱动加载机制,将自定义类加载器替换为系统类加载器,更兼容简化流程 + ### optimize: - [[#6499](https://github.com/apache/incubator-seata/pull/6499)] 拆分 committing 和 rollbacking 状态的任务线程池