This is an automated email from the ASF dual-hosted git repository.
zykkk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 232b6c6f899 [improvement](jdbc catalog) Enhance JDBC driver
ClassLoader cache handling and validity checks (#50353)
232b6c6f899 is described below
commit 232b6c6f8995a48d4a9f0a2c43bb9c8c282ca023
Author: zy-kkk <[email protected]>
AuthorDate: Fri May 9 11:49:38 2025 +0800
[improvement](jdbc catalog) Enhance JDBC driver ClassLoader cache handling
and validity checks (#50353)
Problem Summary:
- Added file-existence checks in initializeClassLoader to catch missing
JARs early
- On “Failed to load driver class” errors, clear stale ClassLoader cache
and retry loading
- mproved exception messages to prompt users to verify driver JAR validity
and retry
**CASE TEST**
- Case 1: Create catalog without jar package
- Error: compute driver checksum from url: mysql-connector-j-8.3.0.jar
meet an IOException: java.io.FileNotFoundException:
/Users/zyk/LocalDoris/doris-run/fe/../jdbc_drivers/mysql-connector-j-8.3.0.jar
(No such file or directory)
- After putting in jar: Successfully created and used
- Case 3: After the jar package is successfully created, delete the jar and
do not restart FE to use catalog
- Normal use
- Case 3: After the jar package is successfully created, delete the jar and
restart FE to use catalog
- Error: Please check that the driver JAR is valid and retry.
- After putting in jar: Normal use
- Case 4: Put in the wrong jar:
- Error: Please check that the driver JAR is valid and retry.
- After putting in the jar: Use normally
---
.../org/apache/doris/jdbc/BaseJdbcExecutor.java | 23 ++++++++++++++++++----
.../doris/datasource/jdbc/client/JdbcClient.java | 22 ++++++++++++++++++---
2 files changed, 38 insertions(+), 7 deletions(-)
diff --git
a/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
b/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
index 7a6263e5232..4688602d07a 100644
---
a/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
+++
b/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
@@ -362,17 +362,31 @@ public abstract class BaseJdbcExecutor implements
JdbcExecutor {
} catch (FileNotFoundException e) {
throw new JdbcExecutorException("FileNotFoundException failed: ",
e);
} catch (Exception e) {
+ String msg = e.getMessage();
+ // If driver class loading failed (Hikari wraps it), clear stale
cache and prompt retry
+ if (msg != null && msg.contains("Failed to load driver class")) {
+ try {
+ URL url = new URL(config.getJdbcDriverUrl());
+ classLoaderMap.remove(url);
+ // Prompt user to verify driver validity and retry
+ throw new JdbcExecutorException(
+ String.format("Failed to load driver class `%s`. "
+ + "Please check that the driver JAR is
valid and retry.",
+ config.getJdbcDriverClass()), e);
+ } catch (MalformedURLException ignore) {
+ // ignore invalid URL when cleaning cache
+ }
+ }
throw new JdbcExecutorException("Initialize datasource failed: ",
e);
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
}
- private synchronized void initializeClassLoader(JdbcDataSourceConfig
config)
- throws MalformedURLException, FileNotFoundException {
+ private synchronized void initializeClassLoader(JdbcDataSourceConfig
config) {
try {
URL[] urls = {new URL(config.getJdbcDriverUrl())};
- if (classLoaderMap.containsKey(urls[0])) {
+ if (classLoaderMap.containsKey(urls[0]) &&
classLoaderMap.get(urls[0]) != null) {
this.classLoader = classLoaderMap.get(urls[0]);
} else {
String expectedChecksum = config.getJdbcDriverChecksum();
@@ -385,7 +399,8 @@ public abstract class BaseJdbcExecutor implements
JdbcExecutor {
classLoaderMap.put(urls[0], this.classLoader);
}
} catch (MalformedURLException e) {
- throw new RuntimeException("Error loading JDBC driver.", e);
+ throw new RuntimeException("Failed to load JDBC driver from path: "
+ + config.getJdbcDriverUrl(), e);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
index 121f7d6ba04..7d3ecdfe4d9 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
@@ -144,7 +144,22 @@ public abstract class JdbcClient {
+ ", ConnectionPoolMaxWaitTime = " +
config.getConnectionPoolMaxWaitTime()
+ ", ConnectionPoolMaxLifeTime = " +
config.getConnectionPoolMaxLifeTime());
} catch (Exception e) {
- throw new JdbcClientException(e.getMessage());
+ // If driver class loading failed (Hikari wraps it), clean cache
and prompt retry
+ String msg = e.getMessage();
+ if (msg != null && msg.contains("Failed to load driver class")) {
+ try {
+ URL url = new
URL(JdbcResource.getFullDriverUrl(config.getDriverUrl()));
+ classLoaderMap.remove(url);
+ // Prompt user to verify driver validity and retry
+ throw new JdbcClientException(
+ String.format("Failed to load driver class `%s`. "
+ + "Please check that the driver JAR is
valid and retry.",
+ config.getDriverClass()), e);
+ } catch (MalformedURLException ignore) {
+ // ignore invalid URL when cleaning cache
+ }
+ }
+ throw new JdbcClientException(e.getMessage(), e);
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
@@ -153,7 +168,7 @@ public abstract class JdbcClient {
private synchronized void initializeClassLoader(JdbcClientConfig config) {
try {
URL[] urls = {new
URL(JdbcResource.getFullDriverUrl(config.getDriverUrl()))};
- if (classLoaderMap.containsKey(urls[0])) {
+ if (classLoaderMap.containsKey(urls[0]) &&
classLoaderMap.get(urls[0]) != null) {
this.classLoader = classLoaderMap.get(urls[0]);
} else {
ClassLoader parent = getClass().getClassLoader();
@@ -161,7 +176,8 @@ public abstract class JdbcClient {
classLoaderMap.put(urls[0], this.classLoader);
}
} catch (MalformedURLException e) {
- throw new RuntimeException("Error loading JDBC driver.", e);
+ throw new RuntimeException("Failed to load JDBC driver from path: "
+ + config.getDriverUrl(), e);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]