我什么时候需要为 jdbc 驱动程序指定 Class.forName(driverName)?

When do I need to specify Class.forName(driverName) for jdbc drivers?

我对何时需要在 Java 中为 JDBC 驱动程序使用 Class.forName(driverName).newInstance() 感到困惑,因为有时我不使用它时一切正常。

我记得听说它不再是必需的,也没有使用它,而且一切都很好......主要是。今天,我收到了:java.sql.SQLException: No suitable driver found... 错误。我做了一些研究,结果发现只有 JDBC 4.0 驱动程序会自动加载。我一直在使用 JTDS 1.3.1,即 JDBC 3.0.

经过一些试验,我发现类路径上有两个版本的 JTDS 1.3.1,一个在 Tomcat 的全局 lib 文件夹中,一个在我的 webapp 的 [=14] =]文件夹。

如果我把它们都留下,我必须调用 Class.forName(driverName).newInstance() 才能正常工作。我想知道的是,为什么这能解决问题?如果这两个罐子是一样的,我不知道它是如何选择“正确”的罐子的。

此外,如果我从 webapp 的 lib 文件夹中取出 jtds jar,如果 jtds 1.3.1 不是 JDBC 4.0 驱动程序?

虽然jTDS不是JDBC4的驱动,但是它确实包含了JDBC4中定义的必要的服务定义文件(META-INF/services/java.sql.Driver),所以它实际上受制于自动驱动加载中。

但是,自动驱动程序加载仅适用于初始 class 路径上的驱动程序。例如 Tomcat,它们是 Tomcat 本身的 lib 目录中的驱动程序。 WEB-INF/lib 文件夹中的驱动程序不受自动驱动程序加载的影响。

我无法具体回答为什么当驱动程序同时在您的应用程序的 Tomcat libWEB-INF/lib 中时会导致问题,但这可能是由于在 class 路径上具有相同 classes 的多个版本导致错误的 classes 或文件被加载,破坏了东西。

顺便说一句,没有必要使用 newInstance()。在过去(20 多年前)有时建议在使用 Class.forName.[= 时在实例初始化器 and/or 有问题的 JVM 而不是 运行 静态初始化器中进行注册的错误驱动程序。 17=]