Monday, September 27, 2021

How to fix java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver [Solution]

This error comes when you try to connect to the Microsoft SQL Server database from the Java program but the required JDBC driver is not available in Classpath or driver is available in CLASSPATH but the class loader is not able to find it due to classpath intricacies. Depending upon your situation, a solution could be as simple as downloading any of sqljdbc.jar, sqljdbc4.jar, or sqljdbc41.jar, based upon the Java version you are using and adding them into CLASSPATH as set CLASSPATH = %CLASSPATH%; (path to Microsoft JDBC driver) in Windows. BTW, in most of the cases "java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver" comes because of classpath intricacies.


For example, if your Java program is using -cp or -classpath option but you added the JAR into the CLASSPATH environment variable or vice-versa.

Similarly, in Java, web application JDBC drivers are required to be present in the WEB-INF/lib directory or if you are running on Tomcat then tomcat/lib directory as well. Finding a solution becomes easy once you know how the classpath concept works in Java, a must-know for any Java developer.

Let's try to find out the real cause of java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver and how to solve this nasty error that is preventing your Java program to connect to Microsoft SQL Server 2008, 2012, or even 2014 database.

By the way, if you really want to understand Java database programming from scratch, I suggest you read the book, Complete JDBC Programming course on Udemy. This course explains every important detail of Java database connectivity and JDBC with a simple example.






Which JDBC Driver JAR to use?

In order to connect to any database including SQL Server from Java program, we use JDBC (Java Database Connectivity) API. This API is present in JDK itself so you don't need any additional JAR to use this but because it has to support different database vendors, it has provided a Driver interface, which is required for database vendors like Oracle, MySQL, or Microsoft SQL Server to implement, if they want to allow their database access via JDBC.

This Driver implementation class is a must for connecting to the database. If you know a little bit of history, there are 4 types of JDBC drivers, but now days almost all databases support type 4, pure Java JDBC driver, which comes as a JAR file and is quite easy to use.

All you need to do is include those JAR e.g. mysql-connector.jar for MySQL, ojdbc6.jar for Oracle 11g database, and sqljdbc4.jar for SQL Server into your Java application's classpath.


Sometimes you may find that there is even multiple JDBC driver JAR available for the same database e.g. sqljdbc.jar, sqljdbc4.jar, or sqljdbc41.jar for the MSSQL database. This is because of different JDBC versions available in different JREs.

The latest version of JDBC is JDBC 4.1 released in Java 7, which is supported by Microsoft in sqljdbc41.jar, and you must use this JAR if you are connecting Microsoft SQL Server 2008 or 2012 from Java 1.7 or Java 1.8. If you use this JAR with a JRE version less than 1.7, you will get exceptions e.g. SQLFeatureNotSupportedException.

Similarly, if you are connecting to SQL Server database from Java 1.6 then use sqljdbc4.jar, which supports JDBC 4.0 version, using this JAR in Java 1.5 will result in an Exception. Similarly, if you are connecting to the MSSQL database from JRE 1.5 then use sqljdbc.jar, which uses JDBC 3.0.

See  Core Java Volume II Advanced Features by Cay S. Horstmann to learn more about new JDBC features introduced in JDBC 3.0 and JDBC 4.0 on JDK 7.




com.microsoft.sqlserver.jdbc.SQLServerDriver

In order to load the JDBC driver from sqljdbc.jar, Java uses Class.forName() method. This method takes the name of the class which implements java.sql.Driver interface as String  and tries to load that class by searching into classpath e.g. Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").

As a result of this method call JVM  (class loader) will look for a class com.microsoft.sqlserver.jdbc.SQLServerDriver in your Java program's classpath. If it doesn't found the class it throws "java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver".

In core Java, it could be your simple Java program that is executing this line and in enterprise Java, it could be a web server or enterprise server or a framework executing this code on your behalf.

java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver



How to fix java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver

As I said, depending upon the individual situation solution to this error could be a little different, but this is what you should try :

1. Check if you have downloaded JDBC Driver for Microsoft SQL Server i.e. any of sqljdbc.jar, sqljdbc4.jar, or sqljdbc41.jar, if not then please download it from here http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11774 and add into CLASSPATH of your Java program.


2. Make sure you download the correct JDBC driver JAR for SQL Server depending upon your Java version e.g. sqljdbc.jar if you are connecting to Microsoft SQL Server from Java 1.5, sqljdbc4.jar if you are running Java 1.6 or sqljdbc41.jar if you are using Java 1.7 or Java 8.


3. Make sure you only add one of these jars, not all of them or even two of them.


4. If you are connecting to Microsoft SQL Server from Tomcat or any enterprise server e.g. JBoss or Weblogic, then make sure you include MSSQL JDBC driver JAR in WEB-INF/lib directory. Sometimes, you also need to add this into tomcat/lib if there are multiple application which is connecting to SQL Server.


5. For core Java application, connecting to SQL Server from Windows environment and using a CLASSPATH environment variable, append the location of sqljdbc4.jar (or the JAR you are using) into CLASSPATH as set CLASSPATH = %CLASSPATH%; {location of driver jar}. Please notice, separator in windows is a semicolon (;)


6. For Java applications connecting to Microsoft SQL Server from UNIX-based systems like Linux include this JAR file into the classpath as export CLASSPATH = ${CLASSPATH} : (directory of driver jar}. Please note, the separator in Linux is a colon(:)

By the way, don't get confused between using the same JAR file in Windows and Linux, Java is platform-independent and that's why you can use the same JAR file on all platforms. Also, even though MSSQL only runs on Windows machines, you can still connect to it from Linux using Java client.


7. If your Java program is using -cp or -classpath option e.g. java -cp {%LIB%} MyProgram, then make sure you include the JDBC driver jar into the LIB environment variable. If you are directly providing the JAR like in simplest cases use :

java -cp .;C:\Program Files\Microsoft JDBC Driver 4.0 for SQL Server\sqljdbc_4.0\enu\sqljdbc.jar


8) If you are running a Java program in Eclipse, make sure you add sqljdbc41.jar (or any JDBC driver JAR) into the build path by selecting your program, right-click, configure the build path.




That's all about how to solve java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver in Java. If you are still not able to solve the problem then please check for different CLASSPATH-related issues as shown in my post about how CLASSPATH works in Java. 

It's not different than solving similar problems comes while connecting to Oracle, MySQL, PostgreSQL, or any other relational database. In most cases, it's just the missing JAR file that causes the problem. In some cases, it's the incorrect JAR file and in some rare cases, it's those classpath mysteries.


Other classpath related issues which comes when you try to connect database from Java program :
  • How to fix java.lang.ClassNotFoundException: org.postgresql.Driver error in Java? [solution]
  • General Guide to solve java.lang.ClassNotFoundException in Java [guide]
  • How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver in Java MySQL? [solution]
  • java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory? [solution]
  • How to solve java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver in Java? [solution]
  • How to solve java.lang.ClassNotFoundException:org.Springframework.Web.Context.ContextLoaderListener [solution]

THanks for reading this article so far. If these tips solve your problem then please share them with your friends and colleagues or on Twitter. I really appreciate the support. 

1 comment:

  1. Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The index 35 is out of range.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setterGetParam(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setString(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.setString(Unknown Source)
    Reason is not SQL SERVER limit but it was number of place holder. I had defined 34 place holder but setting data for 35th column using setString(), setInt() method and that's why JDBC complaining that index 35 is out of range. Remember, first column statarts with index 1 and not zero.

    ReplyDelete