Derby and JDBC version How-To

"Help! Which Derby version am I using?"

Table of Contents

Derby database format version

The Derby database format may change between Derby feature releases (for example 10.1.x -> 10.2.x -> 10.3.x), but will (most likely) not change between releases of the same branch (for example 10.2.1.6 -> 10.2.2.0). Thus, the database format version number will be either 10.0, 10.1, 10.2 or 10.3, etc.

Possible scenario: You want to start using some great new feature in the latest Derby release against your existing database, so you need to do a so-called "hard upgrade" of the database. You are not quite sure which version of Derby you were using when you created the database, which may be useful to know before upgrading.

Possible solution (1): Read the database property DataDictionaryVersion when the database is booted using the most recent JDBC driver version available to you.

Example: Use IJ and the embedded driver from 10.3.1.4 to connect to your database ('tenOneThreeOne', created with the 10.1.3.1 release) and retrieve the version number:

$ java -jar /opt/derby/10.3.1.4/lib/derbyrun.jar ij 
ij version 10.3
ij> connect 'jdbc:derby:tenOneThreeOne';
ij> values syscs_util.syscs_get_database_property( 'DataDictionaryVersion' );
1
------------------------------------------------------------------------------
10.1

Note that this property is not a documented part of Derby's api, so this could change in a future release.

Possible solution (2): Try booting the database using the oldest JDBC driver available to you. If the database format is newer and incompatible, an SQLException (or ij error) will be thrown, detailing the version of the database format.

Example: Use IJ and the embedded driver from 10.0.2.1 to attempt a connection to your (hopefully newer) database.

$ java -cp /opt/derby/10.0.2.1/lib/derby.jar:/opt/derby/10.0.2.1/lib/derbytools.jar org.apache.derby.tools.ij
ij version 10.0
ij> connect 'jdbc:derby:tenThreeOneFour';
ERROR XJ040: Failed to start database 'tenThreeOneFour', see the next exception for details.
ERROR XSLAN: Database at /opt/derby/databases/tenThreeOneFour has an incompatible format with the current version of the software.  The database was created by or upgraded by version 10.3.

Derby jar file version (sysinfo)

Possible scenario: You found out that you have a Derby installation on your hard drive, but you don't know which version it is.

Possible solution: Run sysinfo.

Example: If you have derbyrun.jar available (should be in the lib directory of Derby versions 10.2.1.6 and later), you can do:

java -jar /home/user/derby/lib/derbyrun.jar sysinfo

In the above example, the Derby installation is located in the directory /home/user/derby/ on a Unix/Linux system, and the PATH points to a valid Java installation.

Look for something like this in your output, which will tell you the version of your derby jar files:

--------- Derby Information --------
JRE - JDBC: J2SE 5.0 - JDBC 3.0
[/home/user/derby/lib/derby.jar] 10.3.1.4 - (561794)
[/home/user/derby/lib/derbytools.jar] 10.3.1.4 - (561794)
[/home/user/derby/lib/derbynet.jar] 10.3.1.4 - (561794)
[/home/user/derby/lib/derbyclient.jar] 10.3.1.4 - (561794)
------------------------------------------------------

Here, the version of all the Derby jar files is 10.3.1.4 (SVN revision 561794). Remember that derby.jar contains the embedded JDBC driver, while derbyclient.jar contains the client JDBC driver.

If derbyrun.jar is not available, you probably have an older version of derby. Then you must access sysinfo directly by doing for example:

cd /home/user/derby/lib/
java -cp derby.jar:derbytools.jar:derbyclient.jar:derbynet.jar org.apache.derby.tools.sysinfo

Refer to the documentation on Derby tools for more information about sysinfo.


Derby driver and server version (CLASSPATH)

Possible scenario: You don't know which version of Derby your application is using (that is, which version of Derby is in your CLASSPATH). For example, you have downloaded several products which bundle different versions of Derby and/or Java DB, and you are not quite sure which version your IDE is using.

Possible solution: Use the JDBC API (DatabaseMetaData).

Example: The following Java class demonstrates how to retrieve software version information using the database metadata.

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
/**
 * Checks the version of the Derby software running a database.
 */
public class DerbyVersionChecker {
    
    public static void main(String[] args) {
        try {
            // load the embedded driver
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
            // or the client driver...
            //Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
            
            // replace the following URL with your own, or use an existing connection:
            Connection conn = DriverManager.getConnection("jdbc:derby:testDB;create=true");
            
            // this will print the name and version of the software used for running this Derby system
            DatabaseMetaData dbmd = conn.getMetaData();
            String productName = dbmd.getDatabaseProductName();
            String productVersion = dbmd.getDatabaseProductVersion();
            System.out.println("Using " + productName + " " + productVersion);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }
}

For example, if you are using Derby 10.3.1.4, and derby.jar is in your CLASSPATH, the above class will print:

Using Apache Derby 10.3.1.4 - (561794)

Note: If you are using the client driver, the DatabaseMetaData#getDatabaseProductVersion() method returns the version of the software running the database, that is the version of the Derby Network Server (actually, the server is using the embedded driver to connect to the database). If you want to get the version of your JDBC driver (the Derby client driver) instead, use the DatabaseMetaData#getDriverVersion() method, as shown below. In an embedded scenario the embedded driver itself runs the database, so the two methods will return the same result.

String driverVersion = dbmd.getDriverVersion();

JDBC specification support

Possible scenario: You want to use some special feature that is not available in all versions of JDBC. You are not sure which JDBC version your Java VM supports, but want to find out.

Possible solution: Try to access classes/interfaces introduced in or removed from certain JDBC-related specifications.

Example: The following Java code demonstrates this in a way that is similar to how Derby's test harness determines the level of JDBC support in the current JVM:

    private void printJDBCSupportInVM() {

        /* Check the availability of classes or interfaces introduced in or
         * removed from specific versions of JDBC-related specifications. This
         * will give us an indication of which JDBC version this Java VM is
         * supporting.
         */
        if (haveClass("java.sql.SQLXML")) {
            System.out.println("JDBC 4");
        } else if (haveClass("java.sql.Savepoint")) {
            // indication of JDBC 3 or JSR-169.
            // JSR-169 is a subset of JDBC 3 which does not include the java.sql.Driver interface
            if (haveClass("java.sql.Driver")) {
                System.out.println("JDBC 3");
            } else {
                System.out.println("JSR-169");
            }
        } else if (haveClass("java.sql.Blob")) {
            // new in JDBC 2.0.
            // We already checked for JDBC 3.0, 4.0 and JSR-169, all of which also
            // include this class. Chances are good this is JDBC 2.x
            System.out.println("JDBC 2");
        } else if (haveClass("java.sql.Connection")) {
            // included in most (all?) JDBC specs
            System.out.println("Older than JDBC 2.0");
        } else {
            // JDBC support is missing (or is older than JDBC 1.0?)
            System.out.println("No valid JDBC support found");
        }
    }
   
   /**
    * Checks whether or not we can load a specific class.
    * @param className Name of class to attempt to load.
    * @return true if class can be loaded, false otherwise.
    */
   private static boolean haveClass(String className) {
       try {
           Class.forName(className);
           return true;
       } catch (Exception e) {
           return false;
       }
   }

For example, if you are running a Java SE 6 VM you will have JDBC 4 support, so the printJDBCSupportInVM() method prints:

JDBC 4

Note that Derby JDBC drivers of version 10.2.2.0 and later include support for JDBC 4.


  • No labels