简体   繁体   中英

Driver class can't load for first time

I have one servlet class in which I established connection to MySQL database. This is my code for doGet() method.

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
           //Class.forName("com.mysql.jdbc.Driver");    
        con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","rspl123#");
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    System.out.println(con);
    response.getWriter().write(request.getParameter("q"));

}

For above code, when the servlet is called for the first time, exception is thrown that No suitable driver found . But It runs and connection established successfully for the second time nd onwards.

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/test
at java.sql.DriverManager.getConnection(DriverManager.java:602)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
at controller.FetchSuggestion.doGet(FetchSuggestion.java:44)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)

null
com.mysql.jdbc.JDBC4Connection@1b83048
com.mysql.jdbc.JDBC4Connection@1455d1c
com.mysql.jdbc.JDBC4Connection@1f51e5c

The above code works fine if I remove the comment from Class.forName() , but it won't work without it for first time and able to establish connection for the second time onwards. FYI : I already have MySQL JAVA connector in my class path.

MySQL Java Connector version : 5.1.10
JDK : 1.6
IDE : MyEclipse for Spring

First of , you will need to include the mysql-connector.jar in your classpath. You can download the jar from:

You can then configure your data source connection using the following statements:

  // This will load the MySQL driver, each DB has its own driver
  try
  {
  Class.forName("com.mysql.jdbc.Driver");
  }
  catch(ClassNotFoundException e)
  {
  e.printStackTrace();
  }

  // Now you can setup the connection with the DB
   Connection connection=null;
   try {
    connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database","username", "password");
 } 
 catch (SQLException e) 
 {
    System.out.println("Connection Failed..!");
    e.printStackTrace();
}

Registering the DriverClassName is a vital step . Kindly do not skip it.

EDIT: I think I found your problem. Here's the analysis:

  • The reason your application worked with Class.forName is because you had specifically asked the DriverManager to load this Driver for you .
  • The reason that your application did not work for the first time is because you did not specify the Driver to be used.

Let me elaborate on the second point :

You are absolutely right in saying that the application should work without Class.forName . But aaahhh... There's a catch .

  • When you don't specify Class.forName , the DriverManager will try to load as many drivers as it can find and then for any given connection request, it will ask each driver in turn to try to connect to the target URL.

This means that you might have multiple Drivers in your application . The DriverManager found these drivers and tried to establish a connection to the database . The connection was null because the first driver found wasn't the right one . But wait, DriverManager is smart . It knows it could not connect to the database, so now it uses the other driver found . And presto, the connection gets established.

Check the reference: Driver Interface . It's mentioned in the documentation.

Hope it helps. :)

By looking at the source code for java.sql.DriverManager I see that the code for loading “initial” drivers (ie not explicitly loaded ones) is triggered by the first attempt to get a driver. If another thread tries to get a driver then, the initialize() method does not wait for the ongoing initialization but returns immediately:

static void initialize() {
    if (initialized) {
        return;
    }
    initialized = true;
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}

So it's a race condition. The second thread will skip the initialization without finding a driver but surely complete before the first thread as not doing the initialization takes lesser time. So it appears as if the first attempt fails but it is the second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM