db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Olav Sandstaa <Olav.Sands...@Sun.COM>
Subject Re: Autoloading of JDBC drivers considered harmful?
Date Wed, 31 May 2006 13:28:58 GMT
Knut Anders Hatlen wrote:
> 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.
>   

It seems like your example does not work even if you do a
explicit Class.forName() to reload the driver. The following program
(attempts to) reload the driver after having done a system shutdown:

import java.sql.DriverManager;
import java.sql.SQLException;

class AutoLoad {

   public static void main(String[] args) {
       System.out.println("Load driver 1");
       try {
           Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
       } catch (Exception e) {
           System.out.println("FAIL: Failed to load driver: " + e);
       }

       System.out.println("Unload driver 1");
       try {
           DriverManager.getConnection("jdbc:derby:;shutdown=true");
       } catch (SQLException se) {
           System.out.println("Shutdown returned: " + se);
       }

       try {
           Thread.sleep(1000);
       }
       catch (InterruptedException e) {
           // Ignore exception
       }
       System.gc();

       System.out.println("Load driver 2");
       try {
           Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
       } catch (Exception e) {
           System.out.println("FAIL: Failed to load driver: " + e);
       }

       System.out.println("Unload driver 2");
       try {
           DriverManager.getConnection("jdbc:derby:;shutdown=true");
       } catch (SQLException se) {
           System.out.println("Shutdown returned: " + se);
           }


   }
}

The following output is produced:

  Load driver 1
  Unload driver 1
  Shutdown returned: java.sql.SQLException: Derby system shutdown.
  Load driver 2
  Unload driver 2
  Shutdown returned: java.sql.SQLException: No suitable driver found for 
jdbc:derby:;shutdown=true

So it seems like the second attempt to load the driver does not do
what is intended.

BUT: if you use class.forName(...).newInstance() the driver will be
reloaded the second time. Now the program writes:

  Load driver 1
  Unload driver 1
  Shutdown returned: java.sql.SQLException: Derby system shutdown.
  Load driver 2
  Unload driver 2
  Shutdown returned: java.sql.SQLException: Derby system shutdown.

Regards,
Olav


Mime
View raw message