为什么必须将JDBC驱动程序放在TOMCAT_HOME/lib文件夹中?

为什么必须将JDBC驱动程序放在TOMCAT_HOME/lib文件夹中?,tomcat,jdbc,Tomcat,Jdbc,我有一个奇怪的问题,两个带有Oracle JDBC驱动程序的web应用程序会相互冲突。我必须将JDBC驱动程序JAR放在公共文件夹TOMCAT_HOME/lib中。这是什么原因?JDBC驱动程序在JVM范围的单例中注册,所有web应用程序都共享该单例。如果您从两个不同的web应用程序注册了两次相同的JDBC驱动程序(与类名相同),这可能会导致您的问题。如果您的web应用程序使用同一JDBC驱动程序的不同版本,则问题更大 此外,当您在不重新启动Tomcat的情况下重新部署web应用程序时,将JDB

我有一个奇怪的问题,两个带有Oracle JDBC驱动程序的web应用程序会相互冲突。我必须将JDBC驱动程序JAR放在公共文件夹TOMCAT_HOME/lib中。这是什么原因?

JDBC驱动程序在JVM范围的单例中注册,所有web应用程序都共享该单例。如果您从两个不同的web应用程序注册了两次相同的JDBC驱动程序(与类名相同),这可能会导致您的问题。如果您的web应用程序使用同一JDBC驱动程序的不同版本,则问题更大

此外,当您在不重新启动Tomcat的情况下重新部署web应用程序时,将JDBC驱动程序放入Tomcat的lib文件夹将有助于防止内存泄漏,例如,如果您刚刚将新WAR文件放入Tomcat的webapps文件夹:

DriverManager
由引导类加载器加载,因此在JVM中全局“存在”,而Tomcat在其自己的类加载器中加载所有web应用。因此,如果web应用的web-INF/lib文件夹中的JDBC驱动程序在
DriverManager
中注册,它会将该web应用的类加载器固定在内存中(从而将该web应用的所有类都固定在内存中),从而防止其垃圾收集

相反,如果
DriverManager
和JDBC驱动程序都来自非web应用类加载器,则您可以自由重新部署web应用,而无需将任何web应用类固定在从其他类加载器加载的类中


如果JDBC驱动程序检测到内存泄漏,当前版本的Tomcat(可能是6.x,肯定是7.x)将在取消部署web应用时记录警告。

什么意思会相互冲突?冲突究竟是什么?您使用的是JNDI还是直接JDBC访问?将sql jar放在tomcat“apache-tomcat-7.0.37\lib”的lib文件夹中可以解决这个问题?是的,如果您将一个JDBC驱动程序jar放在tomcat的lib/(而不是web应用程序的lib/)中,这将避免原始海报中描述的冲突。当然,您的所有应用程序都必须能够使用相同的JDBC驱动程序版本。是我一个人,还是“JVM范围的singleton DriverManager”似乎是JDBC设计中的一个主要缺陷?@PhilippReichart这在最新版本的插件中仍然是现实吗?我也有一个类似的问题,我正在努力知道将postgres驱动程序放在什么地方,特别是在为不同的应用程序使用不同版本的驱动程序的情况下。@DavidBrossard在Tomcat的最新版本(如9)中默认不再有“共享”文件夹。默认情况下,“服务器”、“共享”和“公共”类加载器都从同一对位置加载类和jar:Tomcat/Catalina“home”文件夹中的
lib
文件夹,以及Tomcat/Catalina“base”文件夹中的
lib
文件夹。有关注释中的解释,请参见
catalina.properties
文件,如果需要其他配置,请编辑该文件。