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

Posted

技术标签:

【中文标题】Ubuntu Tomcat7 java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory【英文标题】: 【发布时间】:2013-01-20 15:52:59 【问题描述】:

我正在尝试在 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" />

显然,使用正确且经过测试的数据库用户 ID 和密码。当我重新启动 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 相当可疑。 不想死机,但是包名里的双dbcp是对的。 tomcat-dbcp.jar 基本上是commons-dbcp.jar 的重构/重新打包版本,这个包是正确的。 感谢您的提问!也被这个打击了 【参考方案1】:

原因是 Tomcat7 的 Ubuntu 构建/打包过程中存在问题。如果我正确理解了这个问题,Apache 从二进制文件构建 tomcat-dbcp.jar,而 Ubuntu 只从源代码构建包。 Ubuntu 项目最终需要更改 Java 包名称,这往往会给我们这些可怜的用户带来麻烦。血淋淋的细节可以在Ubuntu issues list找到。

我找到的解决方案是在定义资源时给数据源工厂命名。在一种情况下,我有一个 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" />

关键元素是“工厂”声明,它覆盖了内置默认值。

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

【讨论】:

请注意,使用这个factory 意味着您不再使用Tomcat 提供的commons-dbcp 池。 Tomcat 提供的 commons-dbcp 池实际上具有“双”dbcp.dbcp 包名称。这是为了防止与“真正的”commons-dbcp 库发生冲突。 这也适用于最近的 Gentoo 这也是我们在 CentOS 6 和 CentOS 7 上的做法。【参考方案2】:

存储库中的库 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

【讨论】:

天哪,这让我很生气。昨天我花了很多时间来追逐这个 JNDI 问题。这些“维护者”有烟雾测试吗?您应该能够信任发行版中的核心服务器组件,对吧? 哇,我希望他们能马上解决这个问题。多么痛苦!我创建了一个 hack-around,我的池类每次使用硬编码的用户名和密码创建一个新连接。感谢您让我回去并以正确的方式做这件事! 对我来说它不起作用,但我将路径更改为 /usr/share/java/tomcat7/tomcat-dbcp-7.0.30.jar 并且它起作用了 实际上,在 Debian 中,在我将上述文件复制到 usr/share/tomcat7/lib(而不是 /usr/share/java)后,它就起作用了。一开始没有这样的文件,所以我没有替换任何损坏的版本)。 我在一个 EZ2 实例上混合了上述两者。 lib根本不存在,我把它放在/usr/share/java/tomcat7/tomcat-dbcp-7.0.30.jar中。似乎还可以。这就是为什么我从不从存储库安装 Tomcat 而是从他们的网站获取它。您不会获得托管更新,但相比之下,这是一个很小的代价。【参考方案3】:

做到了。

确定如果tomcat-dbcp-7.0.30.jar文件没有以下大小,那么它可能已经损坏,你可能需要用上面的sudo wget命令替换它。

-rw-r--r-- 1 root root 235411 2013 年 5 月 1 日 tomcat-dbcp-7.0.30.jar

lrwxrwxrwx 1 根 2013 年 1 月 10 日 22 日 tomcat-dbcp.jar -> tomcat-dbcp-7.0.30.jar

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

如果您不想修补 tomcat,您也可以(在 CentOS 上)将以下内容添加到 JAVA_OPTS(例如,将其添加到 /usr/share/tomcat/conf/context.xml 中

JAVA_OPTS="-Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory"

【讨论】:

以上是关于Ubuntu Tomcat7 java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat7解决java.lang.OutOfMemoryError: PermGen space

tomcat7 启动项目报错 java.lang.NoSuchMethodError: javax.servlet.ServletContext.getSessionCookieConfig()

eclipse ee+tomcat7 访问servlet报错:java.lang.ClassNotFoundException: com.cn.servlet.LoginServlet

Atomikos、Tomcat、JTA java.lang.ClassCastException

java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory

java.lang.ClassNotFoundException:tomcat 7上的javax.jms.JMSContext