Tomcat8 ClassNotFoundException BasicDataSourceFactory

时间:2017-07-06 09:56:38

标签: java tomcat elastic-beanstalk connection-pooling tomcat8

好的,所以我一直试图让它工作太久了。我的确需要一些输入。我已经阅读了很多关于此问题的不同问题并尝试了多种解决方案,但似乎没有什么对我有用。

我正在尝试在AWS上的环境中设置数据库池。环境配置是: 运行Tomcat 8 Java 8的64位Amazon Linux 2017.03 v2.6.1。

我遇到的问题是我得到了这个例外:

javax.naming.NamingException: Could not create resource factory instance [Root exception is java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory]

我的设置是这样的:

我在WEB-INF / conf / context.xml下放在.war中的第一个context.xml文件,首先是正确的位置吗?

<Context>
<Resource name="jdbc/TestDB"
          auth="Container"
          type="javax.sql.DataSource"
          maxTotal="20"
          maxIdle="10"
          maxWaitMillis="10000"
          username="username"
          password="password"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://database-url.example"/>
</Context>

在这里,我尝试为工厂参数提供不同的值,例如

    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

我还尝试添加org.apache.tomcat.dbcp库,也在我的.war下添加WEB-INF / lib /

我在WEB-INF / web.xml下的.war中有web.xml

<web-app>
. . .
  <resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/TestDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

然后在我的代码中我正在做这个

public class Database {

private static DataSource dataSource;

static {
    try {
        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        dataSource = (DataSource) envCtx.lookup("jdbc/TestDB");
    } catch(NamingException e) {
        e.printStackTrace();
    }
}

public static Connection getPoolConnection() {
    try {
        return dataSource.getConnection();
    } catch(SQLException e) {
        e.printStackTrace();
    }

    return null;
}
}

问题可能归结为库不存在于正确的位置,我已经读过你需要将它添加到CATALINA_HOME / lib,这与我添加库的位置不一样吗?如何在我的AWS环境中将库添加到此文件夹?

我需要进行其他更改或添加其他库吗?

我注意到即使我在.war WEB-INF / lib文件夹中添加库并添加factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"或者像factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"这样的某些东西,它仍然无效。即使我将工厂设置为DataSourceFactory,我仍然会得到BasicDataSourceFactory无法找到的相同例外情况。

我想我需要清楚解释哪个文件或库在哪个文件夹中完全正确。

1 个答案:

答案 0 :(得分:0)

好的,所以我想我找到了解决问题的方法。我不知道这是不是最好的方式,但它似乎对我有用。

我所做的是跳过所有关于xml文件的内容,而不是用java做一切。

我删除了context.xml和web.xml中有关资源的内容。

然后我改变了我的数据库类,使用了我找到的一些默认设置和一些我为我的情况修改的设置:

public class Database {

private static DataSource dataSource;

static {
    // Getting environment variables I have set in server
    String dbName = System.getProperty("DB_NAME");
    String userName = System.getProperty("DB_USERNAME");
    String password = System.getProperty("DB_PASSWORD");
    String hostname = System.getProperty("DB_HOSTNAME");
    String port = "3306"; //System.getProperty("RDS_PORT");

    PoolProperties p = new PoolProperties();
    p.setUrl("jdbc:mysql://" + hostname + ":" + port + "/" + dbName);
    p.setDriverClassName("com.mysql.jdbc.Driver");
    p.setUsername(userName);
    p.setPassword(password);
    p.setJmxEnabled(true);
    p.setTestWhileIdle(false);
    p.setTestOnBorrow(true);
    p.setValidationQuery("SELECT 1");
    p.setTestOnReturn(false);
    p.setValidationInterval(30000);
    p.setTimeBetweenEvictionRunsMillis(30000);
    p.setMaxActive(20);
    p.setInitialSize(5);
    p.setMaxWait(15000);
    p.setRemoveAbandonedTimeout(60);
    p.setMinEvictableIdleTimeMillis(30000);
    p.setMaxIdle(10);
    p.setLogAbandoned(true);
    p.setRemoveAbandoned(true);
    p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" +
            "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
    dataSource = new DataSource();
    dataSource.setPoolProperties(p);
}

public static Connection getPoolConnection() {
    try {
        return dataSource.getConnection();
    } catch(SQLException e) {
        e.printStackTrace();
    }

    return null;
}
}

要了解有关此解决方案的更多信息,我在代码示例Plain Ol'Java

部分的https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html处找到了我的答案