ClassNotFoundException - com.microsoft.jdbc.sqlserver.SQLServerDriver
Asked Answered
P

4

13

I have a web development project using local install of Tomcat 7. I am trying to connect to SQL Server 2012 using Microsoft's driver for jdbc (sqljdbc41.jar).

The sqljdbc41.jar is in my application build path:

enter image description here

and I am exporting it. Furthermore, in the Tomcat application directory lib folder I have also placed a copy of sqljdbc41.jar.

There are no compile errors, but at runtime when I try to load the SQL Server driver I get the following:

ClassNotFoundException - com.microsoft.jdbc.sqlserver.SQLServerDriver

The exception is thrown in the following code block:

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://"+server+":1433;databaseName="+database+";user=sa;password="+password+";";
con = (Connection) DriverManager.getConnection(connectionUrl);

I have seen many posts on this topic without resolution:

  1. java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver : Am I loading the right driver?
  2. https://social.msdn.microsoft.com/Forums/sqlserver/en-US/b425c201-9882-4a48-b049-4004f202b0c6/javalangclassnotfoundexception-commicrosoftsqlserverjdbcsqlserverdriver?forum=sqldataaccess
  3. Getting ClassNotFoundException on code: "Class.forName("com.microsoft.sqlserver.jdbc.SqlServerDriver");"

and many more.

Compiler level 1.7 and a JRE of 1.7 - According to documentation, I believe I am using the correct driver. This also states that the CLASSPATH must be set:

echo $CLASSPATH
/var/common/sqljdbc41.jar

Which it is. Furthermore:

java -version
java version "1.7.0_75"
Java(TM) SE Runtime Environment (build 1.7.0_75-b13)
Java HotSpot(TM)
64-Bit Server VM (build 24.75-b04, mixed mode)

So, why am I still encountering this???

Update

I downloaded the sqljdbc41.jar from Microsoft again - just to be sure that somehow the first jar was not corrupt.

Following Mick Mnemonic's link, I removed the jar from the Java Build path and put the newly downloaded jar into the WEB-INF/lib folder of the web application. I then restarted Eclipse and the Tomcat server and cleaned the Tomcat server, and the project.

Still getting the ClassNotFoundException.

Also, the Eclipse IDE can see the driver: enter image description here

Papillon answered 10/12, 2015 at 20:5 Comment(13)
Have you checked the package structure of the jar already ? Is jtds an option ?Bryantbryanty
@Bryantbryanty Yes, and I can see that particular driver in the archive.Papillon
Have you tried a newer version ? As far as I know a version > 4.1 is available. Using jTDS is not an option ?Bryantbryanty
@Bryantbryanty I am using 4.1 thus sqljdbc41.jar. I am not sure that's an option yet. I will check into it. Thanks, I really do appreciate the help!Papillon
Tomcat will explicitly unset and re-initialize the CLASSPATH variable when it starts up. You probably just need to add the library to catalina.properties as instructed in this blog post.Generator
@MickMnemonic Curious that I need to set the classpath at all since I have the jar physically in the Tomcat lib folder. It should find it there like all other jars I use in the project that are not a part of JDK.Papillon
Did you add the path-to-lib into catalina.properties?Generator
@MickMnemonic - No I did no. Since the jar is in Tomcat's Lib folder, that should not be necessary.Papillon
Are you using Maven? If yes, in the Deployment assembly have you added "Maven Dependencies" as deploy path WEB-INF/lib? (To accomplish. right click on project, go in Properties -> Deployment assembly and add "Maven dependencies"Yonatan
@JoeTaras - No Maven.Papillon
Is there a typo in your question or your code? You are getting an exception ClassNotFoundException - com.microsoft.jdbc.sqlserver.SQLServerDriver looking in jdbc.sqlserver but your import lists sqlserver.jdbcRobbegrillet
I was able to get it to work by simply dropping sqljdbc41.jar into the WEB-INF/lib folder for the project and letting Eclipse discover it. In Project Explorer it looks like this. When you open the Properties dialog for the project and look at the "Libraries" tab of the "Java Build Path" page do you see the driver .jar under "Web App Libraries" like this?Dominion
BTW, when I said "letting Eclipse discover it" I was referring to right-clicking the project name in the Project Explorer tree and choosing "Refresh". That's all it took for me.Dominion
W
8

The code Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")

cannot throw ClassNotFoundException - com.microsoft.jdbc.sqlserver.SQLServerDriver

as the names are different. Is it possible that you have it set up incorrectly in your code?

I downloaded the sqljdbc41.jar from their website and see that the correct name for the class is com.microsoft.sqlserver.jdbc.SQLServerDriver.

$ jar tf sqljdbc41.jar | grep SQLServerDriver.class
com/microsoft/sqlserver/jdbc/SQLServerDriver.class

I just found both names on Microsoft's web documentation, so either they renamed this class (changed its package) at some point, or they have errors on some of their docs.

All you should need to do is drop that .jar in Tomcat's lib directory (e.g.apache-tomcat-7.0.67\lib), and restart Tomcat.

If you have the correct class name, and the right jar in the lib directory, and are still seeing that error, I wonder if you have some sort of typo in your eclipse setup, and deploying from eclipse is somehow forcing an attempt to load that broken class name. (I don't use Eclipse, and I don't know about deploying from there).

Try creating a very simple application (and don't tell eclipse about the MS driver class):

@WebServlet("/")
public class SimpleServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Set response content type
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("<h1>" + "Welcome to the servlet!" + "</h1>");
        try {
            String server = "localhost";
            String database = "testDB";
            String password = "sapassword";

            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            String connectionUrl = "jdbc:sqlserver://"+server+":1433;databaseName="+database+";user=sa;password="+password+";";
            Connection con = (Connection) DriverManager.getConnection(connectionUrl);
        } catch (ClassNotFoundException e) {
            out.println("<h2>" + e.getClass().getSimpleName() + "_" + e.getMessage() + "</h2>");
        } catch (SQLException e){
            out.println("<h2>" + e.getClass().getSimpleName() + "_" + e.getMessage() + "</h2>");
        } finally {
            out.println("<h1>" + "That's the end of the servlet!" + "</h1>");
        }
    }
}

And running it. If you see output like:

Welcome to the servlet!

SQLServerException_The TCP/IP connection to the host localhost, port 1433 has failed. Error: "Connection refused: connect. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".

That's the end of the servlet!

It means that the driver loaded properly. The connection failed b/c I don't have SQLServer instance currently running to test against.

Whelp answered 15/12, 2015 at 21:5 Comment(1)
We found the solution, but because there was a bounty on this post, I was not allowed to delete it, and have been away for several days. There was a hard-coding that was basically ignoring what was being passed in. But you are correct and that subtlety was missed before offering the bounty.Papillon
S
2

You need to add the library to catalina.properties because you are using the DB connection within the context of the container's core functionality, and not just as one of the child applications inside it.

Downvote my answer as you wish, but I only ask you test it first.

Sherry answered 15/12, 2015 at 19:40 Comment(0)
O
1

Looking at all the comments here on this post, I assume that you've tried almost all the options provided. Looking at your snapshots provided above, I assume you are using a Unix/Linux based system for your development. There is a change in the way you update your CLASSPATH variable in Windows and say in Linux. ';' is used in Windows while ':' in Linux. Hope you've taken care of such minor details:

There's a helpful link that I can suggest you to go through, where there are many remedies given to resolve the issue that you are facing: Link

Optime answered 15/12, 2015 at 8:57 Comment(0)
S
1

I think you need to be registered on the dialect class: org.hibernate.dialect.SQLServer2012Dialect

if it were spring project, it is connected to a file application.properties:

spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
    spring.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect
    spring.datasource.url=jdbc:sqlserver:database;user=sa;password=password;
    spring.datasource.username=sa
    spring.datasource.password=password

but here it will be exactly like I do not remember

Swirl answered 21/12, 2015 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.