Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
494 views
in Technique[技术] by (71.8m points)

mysql - When is Class.forName needed when connecting to a database via JDBC in a web app?

According to this tutorial, calling Class.forName isn't needed anymore with JDBC 4.0+ drivers. I successfully followed the method in the example (just calling DriverManager.getConnection) for a stand-alone program using MySQL, but when I tried to connect to the exact same database from a class that was part of a web app running on Tomcat 7, it wouldn't work; instead I got a No suitable driver found exception.

The mysql-connector-java-5.1.18-bin.jar file was in tomcatwebappsDatabaseProjectWEB-INFlib, I triple checked, but it wasn't working, so I started trying things. I added a call to Class.forName and it worked. That was the only thing that changed.

Anyway my question is, does anybody know why this worked or what was going on here? My only theory is that I also have hsqldb.jar in tomcatlib for another project and maybe somehow the drivers got confused? But I was under the impression that DriverManager is supposed to be able to tell automatically which driver to use, so that's not supposed to be an issue... Anyway if someone could enlighten me as to what's going on here, I'd really appreciate it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

JDBC4 drivers include a file:

META-INF/services/java.sql.Driver

in the jar which uses the ServiceProvider mechanism to register the Driver implementation with the JVM (see javadocs for java.util.ServiceLoader). That's why Class.forName is no longer necessary.

My guess is that this is a class loader issue. The ServiceLoader javadoc mentions that:

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.

I would try putting your driver in the tomcatlib directory rather than your web app directory to see if that makes a difference (different class loader?).

If you launch your web app through an ide and set a breakpoint, once you hit the breakpoint, you can use the "evaluate expression" feature to execute: ServiceLoader.load(Driver.class). This will give you a ServiceLoader class which you can peek into to see which Drivers are registered. You can check if the mysql driver is there, where in the list it is, etc, which might help in figuring out the behaviour here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...