2


I'm trying to get access to my database via jsp and I have the following code:

<% 
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String value = "vuoto";


        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/onlinebookstore", "root", "sesame");
        Statement statement = connection.createStatement();
        ResultSet result = statement.executeQuery("SELECT * FROM users WHERE email = '" + username + "' " + "AND" + " password = '" + password + "'");
        if(result.next()) {
           value = "eccomi";
        }
        connection.close();
%>

I don't understand why I need to use Class.forName because I read that from JDBC 4.0 it is not necessary, but if I remove that statement it doesn't work. In my libraries I added MySQL JDBC Driver -mysql-connector-java-5.1.23-bin.jar

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
zer0uno
  • 7,521
  • 13
  • 57
  • 86

4 Answers4

3

I'll ignore the bad programming practice of writing Java code in JSP exposed in the question — you should really start getting used to create a sandbox servlet whenever you want to intercept on HTTP requests/responses using raw Java code rather than HTML.


As to the concrete problem, this is indeed expected behavior. For starters, JDBC 4.0 drivers are auto-loaded using the ServiceLoader API. Let's look at its javadoc; here's an extract of relevance (the 5th paragraph of the javadoc; emphasis mine):

If a particular concrete provider class is named in more than one configuration file, or is named in the same configuration file more than once, then the duplicates are ignored. The configuration file naming a particular provider need not be in the same jar file or other distribution unit as the provider itself. The provider must be accessible from the same class loader that was initially queried to locate the configuration file; note that this is not necessarily the class loader from which the file was actually loaded.

The one responsible for querying the configuration file in JAR's /META-INF/services folder is the servletcontainer itself, not the webapp. So, essentially, the JAR has got to be placed in servletcontainer's own runtime classpath, not the webapp's own runtime classpath. The webapp's /WEB-INF/lib folder is covered by webapp's runtime classpath not the servletcontainer's and hence essentially the wrong place.

You did nowhere tell something about the servletcontainer being used, but based on the stack traces found in some of your other questions, I'd guess that it's Apache Tomcat. In that case, the JDBC driver JAR file has got to be placed in Tomcat's own /lib folder in order to properly utilize the JDBC driver auto-loading by the ServiceLoader mechanism.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

Even though jar is part of classpath, none of the code you have writen has referenced the Driver class. I believe that Driver class registers itself with JDBC in one of its static blocks, and hence it must be loaded by class loader for that static block to execute and for JDBC api to make use of that driver class. Class.forName loads the class and hence it is needed.

Also, as someone had answered and for some reason deleted that post, only drivers compatible with JDBC 4.0 do not require Class.forName, but older drivers do.

Wand Maker
  • 18,476
  • 8
  • 53
  • 87
0

JDBC driver mysql-connector-java-5.1.23-bin.jar is type 4 driver which conforms to the JDBC 3.0 and JDBC 4.0 specifications.

But for taking advantages of JDBC 4.0 specifications you will need java 6 or above.

if you have older java, than it will consider JDBC 3.0 specification and won't load Driver automatically.

You will find this information in the documentation provided within Zip file downloaded.

Kartik73
  • 503
  • 6
  • 19
0

In my environment, this code works without Class.forName.

public class Test {
  public static void main(String[] args) {

    //Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "sesame");

    // do some query
  }
}

So i think your problem can be class loader problem. If you're using Tomcat, this answer will help.

Community
  • 1
  • 1
takagiko
  • 85
  • 6