Tomcat CP 未找到 DB2 驱动程序,但 Commons 工作正常?
Posted
技术标签:
【中文标题】Tomcat CP 未找到 DB2 驱动程序,但 Commons 工作正常?【英文标题】:DB2 driver not found with Tomcat CP but Commons works fine? 【发布时间】:2014-05-23 22:30:15 【问题描述】:我正在使用 tomcat + spring。使用以下配置时:
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
<property name="url" value="url" />
<property name="username" value="user" />
<property name="password" value="pass" />
</bean>
我能够获得连接。但是当我尝试使用Tomcat的CP如下:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
<property name="url" value="url" />
<property name="username" value="user" />
<property name="password" value="pass" />
</bean>
我得到嵌套的根本原因异常:java.lang.ClassNotFoundException: com.ibm.db2.jcc.DB2Driver
我所做的唯一更改是重命名负责创建数据源的类。为什么会这样?如何解决?
更新 - 堆栈跟踪
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.sql.SQLException: com.ibm.db2.jcc.DB2Driver
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
root cause
java.sql.SQLException: com.ibm.db2.jcc.DB2Driver
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:254)
org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:702)
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:634)
org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:488)
org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:144)
org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:127)
spring.controller.ReviewController.getReviewById(ReviewController.java:25)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
root cause
java.lang.ClassNotFoundException: com.ibm.db2.jcc.DB2Driver
java.net.URLClassLoader$1.run(URLClassLoader.java:366)
java.net.URLClassLoader$1.run(URLClassLoader.java:355)
java.security.AccessController.doPrivileged(Native Method)
java.net.URLClassLoader.findClass(URLClassLoader.java:354)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:270)
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:246)
org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:702)
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:634)
org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:488)
org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:144)
org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:127)
spring.controller.ReviewController.getReviewById(ReviewController.java:25)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
【问题讨论】:
你在lib文件夹中准备好jdbc jar文件了吗? @BMW 我必须将它放在 lib 中,否则第一个配置将不起作用... 不,它们属于不同的罐子 @BMW 是的,但我使用的是 eclipse,它在服务器配置后默认添加 tomct/lib。我 100% 确定 Tomact 的 CP 在课程路径上。不是说我的CP失踪了,而是司机——是吗?但它不能丢失,因为第一个配置有效。 我的想法。通过任何更改,Tomcat 的 CP 会忽略 lib 文件夹? 【参考方案1】:我假设在您的配置一中的应用程序中,您的 WEB-INF\lib
folder 中有以下 jars
-
commons-dbcp.jar
jt400.jar
(或者可能是某个版本)。
现在,当使用选项 2 时,这是一个问题,因为我假设类 org.apache.tomcat.jdbc.pool.DataSource
来自 tomcat\lib 文件夹中的 jar,而不是来自 WEB-INF\lib 文件夹。由于org.apache.tomcat.jdbc.pool.DataSource
是由系统类加载器而不是Web 应用程序类加载器加载的,因此它无法从WEB-INF\lib
目录中的jar 中看到类。
因此,要么将 jt400.jar 放入 tomcat\lib
目录,要么将 tomcat-jdbc.jar 包含在 WEB-INF\lib
文件夹中。
【讨论】:
实际上它有效......老实说我不明白为什么。我没有commons-dbcp,但在tomcat/lib中也有tomcat-dbcp(据我所知基本相同)tomcat-jdbc也有。所以这很奇怪,一个CP看到司机,第二个没有。无论如何,答案的道具。 没有注意到由于BasicDataSource
而被忽略的org.apache.tomcat.dbcp.dbcp.BasicDataSource
,我假设您使用的是普通的DBCP。默认情况下,Tomcat 使用 tomcat-jdbc impl 作为其数据源,因此它可能也会被急切地加载到系统类加载器中,而不是 tomcat-dbcp 之一。
也许这就是它的工作原理。再次感谢您以我想要的方式解决问题。【参考方案2】:
问题是您设置了一个新的连接池,用于获取连接。新连接池的新代码需要在类路径上。您是否将该依赖项添加到项目中?
编辑
你用的是什么版本的tomcat?您还可以发布您的完整堆栈跟踪吗?
【讨论】:
你能说得更具体点吗?依赖于 DB2 驱动程序或 Tomcat 的 CP?我使用 Tomcat,所以 CP 必须在类路径上。 DB2 驱动程序也在类路径上,因为第一个配置(使用通用 cp)有效。 7.0.42 一些随机文字,满足评论长度要求 在该版本中,tomcat 连接池应该存在于 lib 中。【参考方案3】:您似乎无法通过 Spring 使用 Tomcat 的 CP 创建数据源(可能是由于 Tomcat 的 CP 使用了一些工厂模式)。我目前的走动如下:
-
将 Tomcat 的 DBCP 定义为 JNDI 资源
将JNDI资源加载到Spring中,更多信息here
另请参阅已接受的答案,因为它以原始问题中所述的方式解决问题。
【讨论】:
以上是关于Tomcat CP 未找到 DB2 驱动程序,但 Commons 工作正常?的主要内容,如果未能解决你的问题,请参考以下文章
未找到合适的默认 RequestUpgradeStrategy
DB2 LUW 版本 10.5.0.10 - 在存储过程中获取警告(未找到)行
使用 Hibernate 将 Java 应用程序从 DB2 迁移到 BigQuery 时出现错误“找到:int64,预期:整数”