Hi Olav and Knut Anders,
Thanks for running these experiments and uncovering this behavior.
Driver-autoloading, of course, is a required JDBC4 feature. If Derby
doesn't play well with driver-autoloading, then we have a Derby bug we
have to fix. Perhaps, if we squint at it, we just have odd behavior that
needs documentation. Or perhaps this is a jdk bug.
Let me summarize the odd behavior:
o Under JDBC4, if you explicitly shut down the Derby engine, then
subsequent calls to DriverManager.getConnection() will fail.
o There is a workaround: Explictly reboot the Derby engine by issuing
Class.forName() on the embedded driver.
You could look at this problem from the following angles:
1) This is a Derby bug which we could fix if we separated driver
initialization from engine booting.
2) This is an odd Derby behavior which we should document: If you
explicitly shut down the engine, then if you want to get a connection
later, you must explicitly reboot the engine.
3) This is a jdk bug. The DriverManager should rerun its autoloading
logic if the registered drivers can't get a connection.
I think we will have a hard time convincing the jdk folks that this is
their bug. So I think the choice comes down to (1) vs. (2). I can see
this go either way. My instinct is to opt for (2) because it seems less
risky.
Hey Dan,
What are your thoughts?
Regards,
-Rick
Knut Anders Hatlen wrote:
Olav Sandstaa <[EMAIL PROTECTED]> writes:
To confirm that this was not something special triggered by the DB2
driver, I ran the same test program loading the Derby Network client,
MySQL and PostgreSQL JDBC drivers. With derby.jar in the class path
the embedded driver and engine are loaded in all cases.
It sounds like the problem is that the loading of the embedded JDBC
driver includes starting and initializing the engine. Other
(non-embedded) databases don't have this problem because loading the
driver simply registers it with the DriverManager. Perhaps we could
solve the problem by separating registration of the driver and startup
of the engine? That is, Class.forName("EmbeddedDriver") only registers
the driver, but no reading of system properties or starting of service
threads happens until getConnection() is called.
Another issue with Derby and autoloading is that it only happens once
per JVM. If you do a getConnection("jdbc:derby:;shutdown=true"), the
driver is unloaded and won't be reloaded unless you do a
Class.forName(). So this code
Connection c = DriverManager.getConnection("jdbc:derby:mydb");
doSomethingWithConnection(c);
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException) { /* shutdown exception */ }
runs fine the first time it is executed, but if it is executed later
within the same JVM, it fails with "no suitable driver".
I admit this is a special case, but at least it shows that you cannot
go through your code and remove all calls to Class.forName(driver) and
expect the autoloading to work automagically with Derby today.