Ubuntu下Tomcat7报错java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory

28

我正在尝试在Ubuntu 12.X下的Tomcat 7中设置JDBC数据源,因此我将以下内容添加到context.xml文件中:

<Resource name="jdbc/myDS" auth="Container" type="javax.sql.DataSource"
    maxActive="5" maxIdle="2" maxWait="5000"
    driverClassName="org.postgresql.Driver" username="usr" password="***" url="jdbc:postgresql://localhost:5432/db" />
显然,使用正确和经过测试的数据库用户名和密码。当我重启Tomcat时,我会收到此错误消息:
Feb 05, 2013 1:10:01 PM org.apache.catalina.core.NamingContextListener addResource
WARNING: Failed to register in JMX: javax.naming.NamingException: Could not create resource factory instance [Root exception is java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory]

我谷歌搜索并发现JDBC驱动程序必须复制到$CATALINA_HOME/lib文件夹中,所以我将postgresql-9.2-1000.jdbc4.jar复制到了/usr/share/tomcat7/lib,但是这没有帮助。我尝试将文件复制到其他位置,但结果相同。

另一种尝试是更改/usr/share/tomcat7/lib中的tomcat-dbcp.jar符号链接,将其从../../java/tomcat-dbcp-7.0.30.jar更改为../../java/tomcat-dbcp.jar。唯一的变化是我只收到一个警告而不是四个,但数据源仍然无法正常工作。

Java版本:

jdoe@sever:~$ java -version
java version "1.7.0_09"
OpenJDK Runtime Environment (IcedTea7 2.3.4) (7u9-2.3.4-0ubuntu1.12.10.1)
OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)

有任何提示,非常欢迎。

干杯。


org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory 中的双重 dbcp 相当可疑。 - Mark Rotteveel
2
不想挖坟,但是包名中的双倍 dbcp 是正确的。tomcat-dbcp.jar 基本上是 commons-dbcp.jar 的重构/重新打包版本,而这个包是正确的。 - lugte098
谢谢您的提问!我也遇到了这个问题。 - Hendy Irawan
6个回答

38

来自代码库的库tomcat-dbcp-7.0.30.jar已损坏。

请使用以下内容替换:

sudo wget -O /usr/share/java/tomcat-dbcp-7.0.30.jar http://search.maven.org/remotecontent?filepath=org/apache/tomcat/tomcat-dbcp/7.0.30/tomcat-dbcp-7.0.30.jar


5
天啊,这让我很生气。昨天我浪费了大量时间追踪这个JNDI问题。这些‘维护者’有进行冒烟测试吗?你应该能够信任发行版中的核心服务器组件,对吧? - Joseph Lust
哇,我希望他们立即修复这个问题。真是太痛苦了!我创建了一个 hack-around,在我的池类中每次都使用硬编码的用户名和密码创建一个新连接。谢谢你让我回去用正确的方式来做这件事! - Thorn
1
对我来说它没有起作用,但是我将路径更改为 /usr/share/java/tomcat7/tomcat-dbcp-7.0.30.jar,然后它就起作用了。 - MoD
实际上,在Debian中,我将上述文件复制到usr/share/tomcat7/lib(而不是/usr/share/java)后,它就可以工作了。一开始并没有这样的文件,所以我也没有替换任何损坏的版本。 - Andreas Tasoulas
1
我在 EZ2 实例上得到了以上两者的混合物。该库根本不存在,所以我将其放置在 /usr/share/java/tomcat7/tomcat-dbcp-7.0.30.jar 中。看起来没问题。这就是为什么我从未从软件库安装 Tomcat,而是从他们的网站获取它。虽然你不会获得受管理的更新,但相比之下这只是一个小代价。 - kaqqao

26

问题在于Ubuntu构建/打包Tomcat7的过程中存在问题。如果我理解正确,Apache从二进制文件构建tomcat-dbcp.jar,而Ubuntu仅从源代码构建软件包。Ubuntu项目最终需要更改Java软件包名称,这往往会给我们这些可怜的用户带来问题。有关详细信息,请参阅Ubuntu问题列表

我找到的解决方案是在定义资源时命名数据源工厂。在一个案例中,我有一个包含以下内容的META-INF/context.xml文件:

<Resource name="jdbc/myDataSource"
    auth="Container"
    type="javax.sql.DataSource"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/myDatabase"
    username="username" password="password"
    validationQuery="SELECT COUNT(*) FROM MY_TABLE"
    factory="org.apache.commons.dbcp.BasicDataSourceFactory" />

关键元素是"factory"声明,它可以覆盖内置的默认设置。

在我们的生产机器上,该资源在server.xml文件的GlobalNamingResources元素中定义。在Ubuntu系统上,只有需要指定工厂。


2
请注意,使用此“工厂”意味着您不再使用Tomcat提供的commons-dbcp池。实际上,Tomcat提供的commons-dbcp池确实具有“双重”的dbcp.dbcp包名称。这是为了避免与“真正的”commons-dbcp库发生冲突。 - Christopher Schultz
这同样适用于最近的 Gentoo。 - comodoro
这就是我们在CentOS 6和CentOS 7上的做法。 - Andrei Nistor

1
在Fedora 20上,我遇到了与Tomcat 7.0.55相关的同样问题。我将文件路径和文件名中的7.0.30替换为7.0.55,这对我起作用了。不确定原因是什么,但是这个文件在tomcat 7的YUM安装中完全丢失了。没有它就无法使用数据库。

1
我在CentOS上也遇到了同样的问题。我通过从网站下载最新的Tomcat副本,并将tomcat-dbcp.jar上传到我的在线服务器库中来解决了这个问题,然后重新启动了服务器 :)

0

做到了。

请确保如果 tomcat-dbcp-7.0.30.jar 文件大小不是以下大小,则可能已损坏,您可能需要使用上面的 sudo wget 命令将其替换。

-rw-r--r-- 1 root root 235411 May 1 2013 tomcat-dbcp-7.0.30.jar

lrwxrwxrwx 1 root root 22 Jan 10 2013 tomcat-dbcp.jar -> tomcat-dbcp-7.0.30.jar


0
如果您不想打补丁Tomcat,您也可以(在CentOS上)将以下内容添加到JAVA_OPTS中(例如通过在/usr/share/tomcat/conf/context.xml中添加它)。
JAVA_OPTS="-Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory"

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