Open denis-komarov opened 4 years ago
The problem remains relevant for the new version GraalVM 19.3.0 Community Edition based on JDK 8.
But in version GraalVM 19.3.0 Community Edition based on JDK 11 the problem is fixed, since the same class loader (jdk.internal.loader.ClassLoaders$AppClassLoader) is used for loading org.graalvm.polyglot.Context class as for JDBC driver class.
Java launcher for JavaScript (js.java):
JavaScript code with JDBC call (test.js):
run it (GraalVM Community Edition 19.3.0 based on JDK8 on Windows 10 x64) like this:
output:
This is due to When the method getConnection is called, the DriverManager will attempt to locate a suitable driver from amongst those loaded at initialization and those loaded explicitly using the same classloader as the current applet or application. java.sql.DriverManager when executing getConnection tries to load the class of the JDBC driver by the class loader of the calling class something like this:
If the loading fails, this driver is considered unavailable for use.
When JavaScript code is executed through context, the calling class for DriverManager is org.graalvm.polyglot.Context.
The org.graalvm.polyglot.Context class is loaded using the Bootstrap class loader (getClassLoader () == null) - this is the main problem!
The JDBC driver class is loaded using the Application class loader (getClassLoader () == sun.misc.Launcher$AppClassLoader).
Therefore, the JDBC driver class, in principle, cannot be loaded through the Bootstrap class loader, because Bootstrap is the parent of Application, which violates the Visibility principle.
So, due to the use of the Bootstrap class loader for org.graalvm.polyglot.Context, any JavaScript application executed through the context cannot create a JDBC connection.