This is an automated email from the ASF dual-hosted git repository.

jianbin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 152a7f9489 bugfix: the drivers in the lib folder cannot be loaded 
(#7354)
152a7f9489 is described below

commit 152a7f948953ed7245b426fa75d599391861c570
Author: funkye <jian...@apache.org>
AuthorDate: Thu May 22 13:40:15 2025 +0800

    bugfix: the drivers in the lib folder cannot be loaded (#7354)
---
 changes/en-us/2.x.md                               |   1 +
 changes/zh-cn/2.x.md                               |   1 +
 .../core/store/db/AbstractDataSourceProvider.java  | 112 +++++++++++----------
 .../seata/server/store/DbcpDataSourceProvider.java |   2 +-
 .../server/store/DruidDataSourceProvider.java      |   2 +-
 .../store/db/AbstractDataSourceProviderTest.java   |  63 ++++++++++++
 6 files changed, 125 insertions(+), 56 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index ff01591bfc..cf0360be89 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -26,6 +26,7 @@ Add changes here for all PR submitted to the 2.x branch.
 ### bugfix:
 
 - [[#7349](https://github.com/apache/incubator-seata/pull/7349)] Resolve 
NullPointerException in EtcdRegistryServiceImplMockTest
+- [[#7354](https://github.com/apache/incubator-seata/pull/7354)] fix the 
drivers in the libs folder cannot be loaded
 - [[#7356](https://github.com/apache/incubator-seata/pull/7356)] fix codecov 
bug
 
 
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index e9fe80130f..2cafefb523 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -27,6 +27,7 @@
 ### bugfix:
 
 - [[#7349](https://github.com/apache/incubator-seata/pull/7349)] 解决 
EtcdRegistryServiceImplMockTest 中的空指针异常
+- [[#7354](https://github.com/apache/incubator-seata/pull/7354)] 
修复lib文件夹中的驱动程序无法加载
 
 ### optimize:
 
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 860d9dc953..f24e4a3992 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,9 @@
  */
 package org.apache.seata.core.store.db;
 
+import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MAX_CONN;
+import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MIN_CONN;
+
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -24,9 +27,7 @@ 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.ShouldNeverHappenException;
 import org.apache.seata.common.exception.StoreException;
 import org.apache.seata.common.executor.Initialize;
@@ -39,12 +40,9 @@ import org.apache.seata.core.constants.DBType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MAX_CONN;
-import static org.apache.seata.common.DefaultValues.DEFAULT_DB_MIN_CONN;
-
 /**
  * The abstract datasource provider
- * 
+ *
  */
 public abstract class AbstractDataSourceProvider implements 
DataSourceProvider, Initialize {
 
@@ -57,18 +55,18 @@ 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 static final String MYSQL_DRIVER_CLASS_NAME = 
"com.mysql.jdbc.Driver";
 
-    private final static String MYSQL8_DRIVER_CLASS_NAME = 
"com.mysql.cj.jdbc.Driver";
+    private static final String MYSQL8_DRIVER_CLASS_NAME = 
"com.mysql.cj.jdbc.Driver";
 
-    private final static String MYSQL_DRIVER_FILE_PREFIX = "mysql-connector-j";
+    private static final String MYSQL_DRIVER_FILE_PREFIX = "mysql-connector-j";
 
-    private final static Map<String, ClassLoader> MYSQL_DRIVER_LOADERS;
+    private static final Map<String, ClassLoader> DRIVER_LOADERS;
 
     private static final long DEFAULT_DB_MAX_WAIT = 5000;
 
     static {
-        MYSQL_DRIVER_LOADERS = createMysqlDriverClassLoaders();
+        DRIVER_LOADERS = createMysqlDriverClassLoaders();
     }
 
     @Override
@@ -87,7 +85,7 @@ public abstract class AbstractDataSourceProvider implements 
DataSourceProvider,
     }
 
     public void validate() {
-        //valid driver class name
+        // valid driver class name
         String driverClassName = getDriverClassName();
         ClassLoader loader = getDriverClassLoader();
         if (null == loader) {
@@ -106,14 +104,21 @@ public abstract class AbstractDataSourceProvider 
implements DataSourceProvider,
                     .map(file -> file.isFile() ? file.getParentFile() : file)
                     .filter(Objects::nonNull)
                     .filter(File::isDirectory)
-                    .map(file -> new File(file, "jdbc"))
+                    // Only the MySQL driver needs to be placed in the jdbc 
folder.
+                    .map(file -> 
(MYSQL8_DRIVER_CLASS_NAME.equals(driverClassName)
+                                    || 
MYSQL_DRIVER_CLASS_NAME.equals(driverClassName))
+                            ? new File(file, "jdbc")
+                            : file)
                     .filter(File::exists)
                     .filter(File::isDirectory)
-                    .distinct().findAny().orElseThrow(() -> new 
ShouldNeverHappenException("can not find jdbc folder")).getAbsolutePath();
+                    .distinct()
+                    .findAny()
+                    .map(File::getAbsolutePath)
+                    .orElseThrow(() -> new ShouldNeverHappenException("cannot 
find jdbc folder"));
             throw new StoreException(String.format(
-                    "The driver {%s} cannot be found in the path %s. Please 
ensure that the appropriate database driver dependencies are included in the 
classpath.", driverClassName, driverClassPath));
+                    "The driver {%s} cannot be found in the path %s. Please 
ensure that the appropriate database driver dependencies are included in the 
classpath.",
+                    driverClassName, driverClassPath));
         }
-
     }
     /**
      * generate the datasource
@@ -139,7 +144,7 @@ public abstract class AbstractDataSourceProvider implements 
DataSourceProvider,
         String driverClassName = 
CONFIG.getConfig(ConfigurationKeys.STORE_DB_DRIVER_CLASS_NAME);
         if (StringUtils.isBlank(driverClassName)) {
             throw new StoreException(
-                String.format("the {%s} can't be empty", 
ConfigurationKeys.STORE_DB_DRIVER_CLASS_NAME));
+                    String.format("the {%s} can't be empty", 
ConfigurationKeys.STORE_DB_DRIVER_CLASS_NAME));
         }
         return driverClassName;
     }
@@ -150,12 +155,12 @@ public abstract class AbstractDataSourceProvider 
implements DataSourceProvider,
      * @return the db max wait
      */
     protected Long getMaxWait() {
-        Long maxWait = CONFIG.getLong(ConfigurationKeys.STORE_DB_MAX_WAIT, 
DEFAULT_DB_MAX_WAIT);
-        return maxWait;
+        return CONFIG.getLong(ConfigurationKeys.STORE_DB_MAX_WAIT, 
DEFAULT_DB_MAX_WAIT);
     }
 
     protected ClassLoader getDriverClassLoader() {
-        return MYSQL_DRIVER_LOADERS.getOrDefault(getDriverClassName(), 
ClassLoader.getSystemClassLoader());
+        return DRIVER_LOADERS.getOrDefault(
+                getDriverClassName(), this.getClass().getClassLoader());
     }
 
     private static Map<String, ClassLoader> createMysqlDriverClassLoaders() {
@@ -168,39 +173,39 @@ public abstract class AbstractDataSourceProvider 
implements DataSourceProvider,
             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());
+                .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 {
-                        loader.loadClass(MYSQL8_DRIVER_CLASS_NAME);
-                        loaders.putIfAbsent(MYSQL8_DRIVER_CLASS_NAME, loader);
-                    } catch (ClassNotFoundException e) {
-                        loaders.putIfAbsent(MYSQL_DRIVER_CLASS_NAME, loader);
+                        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) {
                     }
-                } catch (MalformedURLException ignore) {
-                }
-            });
+                });
         return loaders;
     }
 
@@ -243,8 +248,8 @@ public abstract class AbstractDataSourceProvider implements 
DataSourceProvider,
                 password = ConfigTools.publicDecrypt(password, publicKey);
             } catch (Exception e) {
                 LOGGER.error(
-                    "decryption failed,please confirm whether the ciphertext 
and secret key are correct! error msg: {}",
-                    e.getMessage());
+                        "decryption failed,please confirm whether the 
ciphertext and secret key are correct! error msg: {}",
+                        e.getMessage());
             }
         }
         return password;
@@ -292,5 +297,4 @@ public abstract class AbstractDataSourceProvider implements 
DataSourceProvider,
     protected String getPublicKey() {
         return CONFIG.getConfig(ConfigurationKeys.STORE_PUBLIC_KEY);
     }
-
 }
diff --git 
a/server/src/main/java/org/apache/seata/server/store/DbcpDataSourceProvider.java
 
b/server/src/main/java/org/apache/seata/server/store/DbcpDataSourceProvider.java
index 40bac13085..89335f4086 100644
--- 
a/server/src/main/java/org/apache/seata/server/store/DbcpDataSourceProvider.java
+++ 
b/server/src/main/java/org/apache/seata/server/store/DbcpDataSourceProvider.java
@@ -18,8 +18,8 @@ package org.apache.seata.server.store;
 
 import org.apache.seata.common.ConfigurationKeys;
 import org.apache.seata.common.loader.LoadLevel;
-import org.apache.seata.core.store.db.AbstractDataSourceProvider;
 import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.seata.core.store.db.AbstractDataSourceProvider;
 
 import javax.sql.DataSource;
 import java.sql.Connection;
diff --git 
a/server/src/main/java/org/apache/seata/server/store/DruidDataSourceProvider.java
 
b/server/src/main/java/org/apache/seata/server/store/DruidDataSourceProvider.java
index d259df26f3..c2aaf7cd1a 100644
--- 
a/server/src/main/java/org/apache/seata/server/store/DruidDataSourceProvider.java
+++ 
b/server/src/main/java/org/apache/seata/server/store/DruidDataSourceProvider.java
@@ -20,8 +20,8 @@ import javax.sql.DataSource;
 
 import org.apache.seata.common.ConfigurationKeys;
 import org.apache.seata.common.loader.LoadLevel;
-import org.apache.seata.core.store.db.AbstractDataSourceProvider;
 import com.alibaba.druid.pool.DruidDataSource;
+import org.apache.seata.core.store.db.AbstractDataSourceProvider;
 
 import java.sql.Connection;
 
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 a0d8c9f8fe..222d6dd611 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
@@ -19,14 +19,27 @@ package org.apache.seata.server.store.db;
 import javax.sql.DataSource;
 
 import org.apache.seata.common.loader.EnhancedServiceLoader;
+import org.apache.seata.common.loader.EnhancedServiceNotFoundException;
+import org.apache.seata.config.ConfigurationFactory;
 import org.apache.seata.core.store.db.DataSourceProvider;
+import org.apache.seata.server.lock.LockerManagerFactory;
+import org.apache.seata.server.session.SessionHolder;
+import org.junit.After;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
 
 /**
  */
 @SpringBootTest
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class AbstractDataSourceProviderTest {
 
     private final String dbcpDatasourceType = "dbcp";
@@ -36,29 +49,79 @@ public class AbstractDataSourceProviderTest {
     private final String hikariDatasourceType = "hikari";
 
     private final String mysqlJdbcDriver = "com.mysql.jdbc.Driver";
+    private final String mysql8JdbcDriver = "com.mysql.cj.jdbc.Driver";
+
+    @BeforeAll
+    public static void setUp(ApplicationContext context) {
+        EnhancedServiceLoader.unloadAll();
+        ConfigurationFactory.reload();
+        System.clearProperty("store.db.driverClassName");
+    }
+
+    @AfterEach
+     void tearDown() {
+        EnhancedServiceLoader.unloadAll();
+        ConfigurationFactory.reload();
+        System.clearProperty("store.db.driverClassName");
+    }
+
 
     @Test
+    @Order(1)
     public void testDbcpDataSourceProvider() {
         DataSource dataSource = 
EnhancedServiceLoader.load(DataSourceProvider.class, 
dbcpDatasourceType).provide();
         Assertions.assertNotNull(dataSource);
     }
 
     @Test
+    @Order(2)
+    public void testLoadMysqlDriver() {
+        System.setProperty("loader.path", "/tmp");
+        System.setProperty("store.db.driverClassName", mysqlJdbcDriver);
+        DataSource dataSource = 
EnhancedServiceLoader.load(DataSourceProvider.class, 
dbcpDatasourceType).provide();
+        Assertions.assertNotNull(dataSource);
+        System.setProperty("store.db.driverClassName", mysql8JdbcDriver);
+        dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, 
dbcpDatasourceType).provide();
+        Assertions.assertNotNull(dataSource);
+    }
+
+    @Test
+    @Order(3)
+    public void testLoadDMDriver() {
+        System.setProperty("store.db.driverClassName", 
"dm.jdbc.driver.DmDriver");
+        DataSource dataSource = 
EnhancedServiceLoader.load(DataSourceProvider.class, 
dbcpDatasourceType).provide();
+        Assertions.assertNotNull(dataSource);
+    }
+
+    @Test
+    @Order(4)
+    public void testLoadDriverFailed() {
+        System.setProperty("store.db.driverClassName", 
"dm.jdbc.driver.DmDriver1");
+        Assertions.assertThrows(EnhancedServiceNotFoundException.class, () -> {
+            EnhancedServiceLoader.load(DataSourceProvider.class, 
dbcpDatasourceType).provide();
+        });
+    }
+
+    @Test
+    @Order(5)
     public void testDruidDataSourceProvider() {
         DataSource dataSource = 
EnhancedServiceLoader.load(DataSourceProvider.class, 
druidDatasourceType).provide();
         Assertions.assertNotNull(dataSource);
     }
 
     @Test
+    @Order(6)
     public void testHikariDataSourceProvider() {
         DataSource dataSource = 
EnhancedServiceLoader.load(DataSourceProvider.class, 
hikariDatasourceType).provide();
         Assertions.assertNotNull(dataSource);
     }
 
     @Test
+    @Order(7)
     public void testMySQLDataSourceProvider() throws ClassNotFoundException {
         ClassLoader classLoader = ClassLoader.getSystemClassLoader();
         Class<?> driverClass = Class.forName(mysqlJdbcDriver, true, 
classLoader);
         Assertions.assertNotNull(driverClass);
     }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org

Reply via email to