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\libfolder 中有以下 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 工作正常?的主要内容,如果未能解决你的问题,请参考以下文章

DB2数据库显示未启动,但是可以连接到

未找到 Openshift Tomcat 404

未找到合适的默认 RequestUpgradeStrategy

面对 DB2 中的“未找到合并的行”错误

DB2 LUW 版本 10.5.0.10 - 在存储过程中获取警告(未找到)行

使用 Hibernate 将 Java 应用程序从 DB2 迁移到 BigQuery 时出现错误“找到:int64,预期:整数”