Tomcat 7.0 JDBC连接池和MySql出现SQLException问题

5
我正在尝试使用新的Tomcat 7.0 JDBC连接池和MySql。这里说,您可以将最新的tomcat-jdbc.jar放入Tomcat 6.0环境中的tomcat / lib目录中,这就是我所做的。
我正在使用Spring根据网上的示例初始化和实例化DataSource:
<bean id="myDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close" 
p:driverClassName="${driver_class}"
p:url="${url}"
p:username="${username?root}"
p:password="${password}"
p:initialSize="10"
p:initSQL="SELECT DTS FROM DT_TM_TS FOR READ ONLY WITH UR"
p:minIdle="10"
p:maxIdle="100"
p:maxActive="100"
p:maxWait="6000"
p:jmxEnabled="true"
p:jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
p:removeAbandoned="true"
p:removeAbandonedTimeout="60"
p:logAbandoned="true"
p:testOnBorrow="true"
p:testOnReturn="false"
p:testWhileIdle="false"
p:useEquals="false"
p:fairQueue="false"
p:timeBetweenEvictionRunsMillis="30000"
p:minEvictableIdleTimeMillis="30000"
p:validationInterval="1800000"
p:validationQuery="SELECT DTS FROM DT_TM_TS FOR READ ONLY WITH UR"
/>   

然而,当我尝试连接到数据库时,它抛出了这个异常:
java.sql.SQLException: "com.mysql.jdbc.Driver"
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:243)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:176)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:647)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:589)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:452)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:130)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:99)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:110)
    at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:46)
    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:111)
    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2101)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1325)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:529)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:495)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:656)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:629)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:338)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)
    at org.apache.catalina.core.StandardService.start(StandardService.java:519)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
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:307)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    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:236)
    ... 59 more

我已经在webapp WEB-INF/lib和tomcat/lib中都有mysql-connector-java-5.1.13-bin.jar。我可以连接到数据库,通过在persistence.xml中指定驱动程序细节(没有DataSource/connection pooling)。

你是否也更新了数据源定义中 resource 标签的 factory 属性?此外,这个堆栈跟踪看起来不完整(是吗?)。 - Tomasz Krzyżak
不,DataSource并不是由Tomcat的DataSourceFactory创建的,而是由Spring创建的。顺便说一下,我现在正在Tomcat 6 Web容器中运行,问题仍然存在。 - Chuck Stephanski
3个回答

6

对于这个问题,Spring 有一个非常简单的解决方法。不要让 Tomcat 连接池创建数据库连接并因为类加载器问题而失败,让 Spring 创建它并将引用传递给连接池即可。

<!-- Data source template for use in the connection pool. -->
<bean id="dataSourceTemplate" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

<!-- Connection pool as data source. -->
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
    <!-- Refer to a separately created bean as a data source template to work around a quirk of Tomcat's class loader. -->
    <property name="dataSource" ref="dataSourceTemplate" />
    ...
</bean>

然后连接池将实际使用数据库连接作为模板,以创建所需的尽可能多的其他连接。

最好的部分是你不必去破坏可能甚至没有访问权限的tomcat/lib文件夹。


2
我使用的是Spring 3.1,Hibernate 4.0,VMware vFabric tc Server Developer Edition 2.6.1与Tomcat 7.0.20.B和Maven 3。由于连接器由Maven管理,我遇到了相同的问题。
实际上,在阅读手册时,我发现:
驱动程序类名(driverClassName)
(字符串)要使用的JDBC驱动程序的完全限定Java类名。驱动程序必须从与tomcat-jdbc.jar相同的类加载器中访问 因此,我通过将mysql连接器(mysql-connector-java-5.1.18-bin.jar)添加到Tomcat的lib目录(vfabric-tc-server-developer-2.6.1.RELEASE/tomcat-7.0.20.B.RELEASE/lib)中,并在Maven中将连接器包的范围设置为提供,解决了这个问题。

0
在Tomcat 6.0中,我需要将我的JDBC驱动程序放入common/lib/ext目录中。
但是,搜索路径是在catalina.properties文件中配置的,请查看其中的common.loader属性。确保common/lib已列出。

这在Tomcat 5.5和Tomcat 6.0之间有所改变。在6.0中不再有/common。6.0的common.loader默认为${catalina.home}/lib,${catalina.home}/lib/*.jar,这是完全可以的,并且表明您需要将JAR文件放入/lib中。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接