JDBC DriverManager never updated for system classloader?
Charles Oliver Nutter
headius at headius.com
Mon Nov 3 15:55:33 UTC 2025
On Sun, Nov 2, 2025 at 3:08 AM Alan Bateman <alan.bateman at oracle.com> wrote:
> I don't think it's possible to engage on the question as to why
> DriverManager does a visibility check. The discovery and and driver
> registration in this API date back to early JDK releases and have been
> very problematic to secure. I think (need Lance to confirm) that the
> hope was that the eco system would move to DataSource but it seems there
> is still a lot of usage of DriverManager.
>
I don't want to get into that quagmire either. I know this code is from the
distant past and has been troublesome to migrate forward.
However, I think the intent of the code can be restored with a simple patch:
```diff
diff --git a/src/java.sql/share/classes/java/sql/DriverManager.java
b/src/java.sql/share/classes/java/sql/DriverManager.java
index 2f51dee5e70..328d5f19946 100644
--- a/src/java.sql/share/classes/java/sql/DriverManager.java
+++ b/src/java.sql/share/classes/java/sql/DriverManager.java
@@ -588,7 +588,9 @@ private static Connection getConnection(
* or bundled with an application, is found.
*/
ClassLoader callerCL = caller != null ? caller.getClassLoader() :
null;
- if (callerCL == null || callerCL ==
ClassLoader.getPlatformClassLoader()) {
+ if (callerCL == null ||
+ callerCL == ClassLoader.getSystemClassLoader() ||
+ callerCL == ClassLoader.getPlatformClassLoader()) {
callerCL = Thread.currentThread().getContextClassLoader();
}
```
I believe the original goal of the `callerCL == null` check was to allow
driver load requests from the system/boot classloader to fall back on the
thread context classloader, since such classes used to have
`getClassLoader` as null. But with the module change, that classloader is
now an instance of `ClassLoaders::AppClassLoader` and neither null nor ==
`getPlatformClassLoader`. My patch above restores the original intent by
also checking if the callerCL is the same classloader as
`getSystemClassLoader`, the default base application classloader now.
This change fixes the reported issue:
```
$ JAVA_HOME=build/macosx-aarch64-server-release/images/jdk/ jruby -r
'jdbc/sqlite3' -e 'Jdbc::SQLite3.load_driver' -e
'java.sql.DriverManager.get_connection("jdbc:sqlite:local.db")'
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::load has been called by
org.sqlite.SQLiteJDBCLoader in an unnamed module
(file:/Users/headius/work/jruby/lib/ruby/gems/shared/gems/jdbc-sqlite3-3.46.1.1/lib/sqlite-jdbc-3.46.1.1.jar)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for
callers in this module
WARNING: Restricted methods will be blocked in a future release unless
native access is enabled
```
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20251103/dea89bd7/attachment-0001.htm>
More information about the core-libs-dev
mailing list