UnsupportedClassVersionError – huh?!
I was recently doing some testing with the new SQL Server 2005 v2.0 JDBC driver and couldn’t get the code to run. Now, as anybody who does Java development in a text editor like myself knows, it is pretty easy to get the wrong CLASSPATH going if you occasionally work with different JDBC driver versions.
So, I immediately checked my CLASSPATH, figuring I had a typo somewhere in there. However, I was surprised to find that it was correct. So why the heck was I getting a CLASSPATH error? Then, I looked closer at the error and realized it was not ClassNotFoundException, but instead was UnsupportedClassVersionError. What the heck? I have been supporting JDBC for more than four year now and I didn’t recall every seeing that before! So, I started looking at what had changed on my machine.
After poking around a little, I remembered I had just rebuilt my machine a few weeks back. However, I didn’t remember installing a JVM. Yet, somehow I was able to run Java and Javac, so that meant some application had installed the JDK. But what version was installed?
A quick jump out to a command prompt and a “javac –version” showed that I was running the 1.4 version of the JDK. 1.4?! That version of the JVM is not supported by the 2.0 JDBC driver!
Just to confirm my suspicions, I wired up a quick batch file and ran some of my stock Java connectivity test code:
Here’s the batch file:
@echo off
echo Confirm we have the ClassPath set to the 2.0 driver
Set CLASSPATH=.;C:\JDBC\sqljdbc_2.0\enu\sqljdbc.jar
set classpath
echo.
echo.
echo Confirm we have the 1.5 JDK
C:\j2sdk1.5\bin\java -version
echo.
echo.
echo Compile and run the sample code with 1.5
C:\j2sdk1.5\bin\javac MSversion.java
C:\j2sdk1.5\bin\java MSversion
echo.
echo.
echo Confirm we have the 1.4 JDK
C:\j2sdk1.4.2_19\bin\java -version
echo.
echo.
echo Now, compile and run the sample code with 1.4
C:\j2sdk1.4.2_19\bin\javac MSversion.java
C:\j2sdk1.4.2_19\bin\java MSversion
and here’s the Java code:
import java.*;
import java.sql.*;
import java.util.*;
import java.text.*;
class MSversion
{
public static void main(String[] args) throws Exception
{
// Load the JDBC driver
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
// Connect to SQL Server
Connection conn = null;
String url = "jdbc:sqlserver://myserver;DatabaseName=master;";
// Process the command line input
if (args.length == 0)
{
// Connect with default id/password
conn = DriverManager.getConnection(url, "username", "password");
//conn = DriverManager.getConnection(url);
}
else if (args.length == 2)
{
// Connect with user-provided username and password
String userName = args[0];
String password = args[1];
conn = DriverManager.getConnection(url, userName, password);
}
else if (args.length == 3)
{
// Connect with user-provided username and password and url
String userName = args[0];
String password = args[1];
url= args[2];
conn = DriverManager.getConnection(url, userName, password);
}
else
{
// Invalid command -> throw an exception
throw new Exception("\nUsage: java version [userName password]\n");
}
// Driver information
DatabaseMetaData dm = conn.getMetaData();
System.out.println("Connected to " + dm.getURL());
System.out.println("Driver Information");
System.out.println("\tDriver Name: " + dm.getDriverName());
System.out.println("\tDriver Version: " + dm.getDriverVersion());
System.out.println("\tDatabase Major Version: " + dm.getDatabaseMajorVersion());
System.out.println("\tDatabase Minor Version: " + dm.getDatabaseMinorVersion());
System.out.println();
// Cleanup
dm=null;
conn.close();
conn=null;
}
}
Lastly, here’s the output:
Confirm we have the ClassPath set to the 2.0 driver CLASSPATH=.;C:\JDBC\sqljdbc_2.0\enu\sqljdbc.jar Confirm we have the 1.5 JDK java version "1.5.0_19" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_19-b02) Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_19-b02, mixed mode) Compile and run the sample code with 1.5 Connected to jdbc:sqlserver://myserver:1433;xopenStates=false;trustServerCertificate=false; sendStringParametersAsUnicode=true;selectMethod=direct;responseBuffering=adaptive; packetSize=8000;loginTimeout=15;lockTimeout=-1;lastUpdateCount=true;encrypt=false; disableStatementPooling=true;databaseName=master;applicationName=Microsoft SQL Server JDBC Driver; Driver Information Driver Name: Microsoft SQL Server JDBC Driver 2.0 Driver Version: 2.0.1803.100 Database Major Version: 9 Database Minor Version: 0 Confirm we have the 1.4 JDK java version "1.4.2_19" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_19-b04) Java HotSpot(TM) Client VM (build 1.4.2_19-b04, mixed mode) Now, compile and run the sample code with 1.4 java.lang.UnsupportedClassVersionError: com/microsoft/sqlserver/jdbc/SQLServerDriver (Unsupported major.minor version 49.0) at java.lang.ClassLoader.defineClass0(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:539) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123) at java.net.URLClassLoader.defineClass(URLClassLoader.java:251) at java.net.URLClassLoader.access$100(URLClassLoader.java:55) at java.net.URLClassLoader$1.run(URLClassLoader.java:194) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:187) at java.lang.ClassLoader.loadClass(ClassLoader.java:289) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274) at java.lang.ClassLoader.loadClass(ClassLoader.java:235) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:141) at MSversion.main(MSversion.java:11) Exception in thread "main"
At this point, I knew all I had to do was point my PATH to either the 1.5 or 1.6 JDK and I should be fine.