I'm trying to load the JDBC driver dynamically with this kind of code:
try{
URL[] url={new URL("file:libs/mysql-connector-java-5.1.21.jar")};
URLClassLoader loader = new URLClassLoader(url, System.class.getClassLoader());
loader.loadClass(drivername);
Enumeration<Driver> drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()){
Driver driver = drivers.nextElement();
System.out.println("driver:"+driver);
}
Class.forName(drivername, true, loader);
drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()){
Driver driver = drivers.nextElement();
System.out.println("driver:"+driver);
}
Connection connect = DriverManager.getConnection(jdbcurl, user,
password);
return connect;
}
catch (MalformedURLException e){
e.printStackTrace();
return null;
}
The first while-loop shows the drivers of the classpath:
driver:sun.jdbc.odbc.JdbcOdbcDriver@35712651
driver:oracle.jdbc.OracleDriver@58df0438
driver:com.ibm.db2.jcc.DB2Driver@525c7734
driver:SQLServerDriver:1
and the second loop shows the same drivers, but without the MySQL driver.
My Question is why? Did I miss something?
I read in the JavaDoc of DriverManager
that every driver tries to register himself by the drivermanager, if the driver is loaded. In my Code this should be loader.loadClass(drivername);
. I thought this code should invoke the static part for example:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
of the Driver
class.
Before using JDBC to access data in a server database file, you need to register the IBM® Toolbox for Java™ JDBC driver with the DriverManager. To load the IBM Toolbox for Java JDBC driver, add the following to the Java program before the first JDBC call: Class. forName("com.
The most common approach to register a driver is to use Java's Class. forName() method, to dynamically load the driver's class file into memory, which automatically registers it.
Type 1: JDBC-ODBC bridge. Type 2: partial Java driver. Type 3: pure Java driver for database middleware. Type 4: pure Java driver for direct-to-database.
A JDBC driver uses the JDBC™ (Java Database Connectivity) API developed by Sun Microsystems, now part of Oracle, that provides a standard way to access data using the Java™ programming language. Using JDBC, an application can access a variety of databases and run on any platform with a Java Virtual Machine.
You cannot do it this way, because DriverManager
doesn't allow you to use drivers that the calling code doesn't have access to (i.e. drivers loaded by different classloader):
When the method
getConnection
is called, theDriverManager
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.
As far as I know the only possible workaround is to instantiate Driver
manually instead of using DriverManager
(assuming that it has a no-arg constructor):
Driver driver = Class.forName(drivername, true, loader).newInstance();
Connection connect = driver.connect(url, props);
Though I'm not sure that it's a correct approach.
that's a known issue with DriverManager and classloaders, see:
http://www.kfu.com/~nsayer/Java/dyn-jdbc.html
Driver definition (basically a delegate):
class DriverShim implements Driver {
private Driver driver;
DriverShim(Driver d) { this.driver = d; }
public boolean acceptsURL(String u) throws SQLException {
return this.driver.acceptsURL(u);
}
public Connection connect(String u, Properties p) throws SQLException {
return this.driver.connect(u, p);
}
// and so on....
Use example:
URL u = new URL("jar:file:/path/to/pgjdbc2.jar!/");
String classname = "org.postgresql.Driver";
URLClassLoader ucl = new URLClassLoader(new URL[] { u });
Driver d = (Driver)Class.forName(classname, true, ucl).newInstance();
DriverManager.registerDriver(new DriverShim(d));
DriverManager.getConnection("jdbc:postgresql://host/db", "user", "pw");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With