我在哪里为Tomcat的连接池放置JDBC驱动程序? [英] Where do I have to place the JDBC driver for Tomcat's connection pool?
问题描述
所以我已经弄清楚了我的错误,现在我只是在寻找一些关于究竟发生了什么的见解。我正在使用Apache Tomcat版本7.0.32。我正在使用
另请参阅:
- 臭名昭着的java.sql.SQLException:找不到合适的驱动程序
- 我该如何连接基于servlet的应用程序中的JDBC数据库/数据源?
- 在多线程系统中使用静态java.sql.Connection实例是否安全?
So I've figured out my error, now I'm just looking for some insight as to what is going on exactly. I am using Apache Tomcat Version 7.0.32. I am using this tutorial to set up pooling for JDBC. In my META-INF folder I made a context.xml file and put this in there.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource type="javax.sql.DataSource" name="jdbc/gmustudent"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/official"
username="root" password="root"
maxActive="100" maxIdle="20" minIdle="15" initialSize="15" maxWait="10000" />
</Context>
I got this error when I wrote this
WARNING: Unexpected exception resolving reference
java.sql.SQLException: com.mysql.jdbc.Driver
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:254)
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:699)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:631)
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:485)
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:143)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:539)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:237)
at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:143)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
at org.apache.naming.NamingContext.lookup(NamingContext.java:843)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1061)
at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:671)
at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:270)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5173)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:246)
... 29 more
Oct 31, 2012 11:23:25 AM org.apache.catalina.core.NamingContextListener addResource
WARNING: Failed to register in JMX: javax.naming.NamingException: com.mysql.jdbc.Driver
Oct 31, 2012 11:23:25 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8086"]
Oct 31, 2012 11:23:25 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Oct 31, 2012 11:23:25 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 794 ms
This error only comes up when I have this statement in my context.xml file. When I remove it no error.
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
The reason I want to make sure that I have it is because in the apache tomcat tutorial it says
factory is required, and the value should be org.apache.tomcat.jdbc.pool.DataSourceFactory
So then I did a little bit of research on SO and found a post saying that you need to add this jar to your lib folder if you have an older version of tomcat. So I added the jar and now it works but I would like to have some information as to what on earth is going on because I am using the newest tomcat version. So why when I specify a factory do I get an error. And what is this jar that I'm adding in and why is there very little documentation about it? Any information about what is going on here would be greatly appreciated.
The JDBC driver has to be visible to the same classloader as the data source factory itself. The data source factory library is placed in Tomcat's own /lib
folder and thus loaded by Tomcat's "common" classloader.
Your problem sounds much like that you dropped the JDBC driver in webapp's /WEB-INF/lib
. The webapp's /WEB-INF/lib
is invisible to the "common" classloader. So technically, you have to place the JDBC driver in Tomcat's own /lib
folder (or, at least, in a configurable path as specified by common.loader
setting in /conf/catalina.properties
) in order to make it visible to the data source factory.
Or, as you attempted, copying the data source factory into /WEB-INF/lib
will also fix it. The webapp's /WEB-INF/lib
has namely higher precedence in classloading than Tomcat's /lib
folder. So if the data source factory is found in /WEB-INF/lib
, it will be loaded from there. As the JDBC driver is also there, it will be seen. This is however not the right solution to your concrete problem, this is more a workaround, so you shouldn't do this.
There isn't exactly documentation which is specifically targeted to this issue. The Tomcat Class Loader HOW-TO will however help in understanding the class loading hierarchy in Tomcat.
See also:
- The infamous java.sql.SQLException: No suitable driver found
- How should I connect to JDBC database / datasource in a servlet based application?
- Is it safe to use a static java.sql.Connection instance in a multithreaded system?
这篇关于我在哪里为Tomcat的连接池放置JDBC驱动程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!