Tomcat8 ClassNotFoundException 基本数据源工厂

Tomcat8 ClassNotFoundException BasicDataSourceFactory

好的,我已经尝试让它工作太久了。我真的需要为我的案子提供一些意见。我已经阅读了很多关于此的不同问题并尝试了多种解决方案,但似乎对我没有任何帮助。

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

我 运行 遇到的问题是我遇到了这个异常:

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 库,也在我的 WEB-INF/lib/

下的 .war 中

我的 .war 在 WEB-INF/web 下有 web.xml。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 的相同异常。

我想我需要一些明确的解释,说明哪些文件或库究竟在哪个文件夹中。

好的,我想我已经想出了解决它的方法。虽然我不知道这是否是最好的方法,但它似乎对我来说非常有用。

我所做的是跳过关于 xml 文件的所有内容,而是在 java 中执行所有操作。

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

然后我像这样更改了我的数据库 class,使用我找到的一些默认设置和我为我的案例修改的一些设置:

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;
}
}

要阅读有关此解决方案的更多信息,我在此处 https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html 代码示例普通 Ol' Java

部分找到了答案