java.sql.DriverManager.getCallerClass() exception handling
Nestor Urquiza
nestor.urquiza at gmail.com
Thu Oct 11 10:57:40 PDT 2012
Hello guys,
I believe the implementation for java.sql.DriverManager.getCallerClass()
has a problem at least in JDK6. Let us see this with the code from "openjdk
6-b14". Swallowing the Exception below is IMO *not good*:
<code>
491 try {
492 callerC = Class.forName(driverClassName, true,
callerClassLoader);
493 }
494 catch (Exception ex) {
495 callerC = null; // being very careful
496 }
</code>
It becomes clear why with the below code
from java.sql.DriverManager.getConnection(). What happens if the method
above throws a ClassNotFoundException<http://docs.oracle.com/javase/6/docs/api/java/lang/ClassNotFoundException.html>
?
<code>
609 for (int i = 0; i < drivers.size(); i++) {
610 DriverInfo di = (DriverInfo)drivers.elementAt(i);
611
612 // If the caller does not have permission to load the driver
then
613 // skip it.
614 if ( getCallerClass(callerCL, di.driverClassName ) !=
di.driverClass ) {
615 println(" skipping: " + di);
616 continue;
617 }
618 try {
619 println(" trying " + di);
620 Connection result = di.driver.connect(url, info);
621 if (result != null) {
622 // Success!
623 println("getConnection returning " + di);
624 return (result);
625 }
626 } catch (SQLException ex) {
627 if (reason == null) {
628 reason = ex;
629 }
630 }
631 }
632
633 // if we got here nobody could connect.
634 if (reason != null) {
635 println("getConnection failed: " + reason);
636 throw reason;
637 }
</code>
Basically if there was a previous error like a non suitable inspected
driver we get that as the cause of the failure when in reality we have not
loaded all drivers we intended to load.
I got into this issue after having a random problem (in some Talend jobs if
you mind to know) through which the jtds driver could not be found but
since the sqlite driver was already loaded the error trace looked like if
our code would try to access a MSSQL URL from a sqlite driver:
<quote>
java.sql.SQLException: invalid database address:
jdbc:jtds:sqlserver://mssql.sample.com:1433//Appdata;appName=MyApp;
at org.sqlite.JDBC.createConnection(JDBC.java:74)
at org.sqlite.JDBC.connect(JDBC.java:64)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
</quote>
As I said our code does work most of the time but for some reason (probably
related to deployment) we get the alert above from time to time.
Am I missing something or this is indeed a bug which resolution is as
simple as changing the method as below (or just call directly
Class.forName() from the getConnection() method)?:
private static Class
<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Class.java#Class>
<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/sql/DriverManager.java#>getCallerClass(ClassLoader
<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/ClassLoader.java#ClassLoader>
callerClassLoader,
<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/sql/DriverManager.java#>
String
<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java#String>
driverClassName) throws Exception {
callerC = Class.forName<http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Class.java#Class.forName%28java.lang.String%2Cboolean%2Cjava.lang.ClassLoader%29>
(driverClassName, true, callerClassLoader);
return callerC;
}
Thanks!
-Nestor
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/jdk6-dev/attachments/20121011/73e87bad/attachment.html
More information about the jdk6-dev
mailing list