方法com / mysql / jdbc / PreparedStatement.isClosed()Z是抽象的

时间:2020-12-01 11:55:31

I'm trying to change the connection pool of my app, in order to use Tomcat's connection pool (org.apache.tomcat.jdbc.pool) instead of "Apache Commons DBCP".

我正在尝试更改我的应用程序的连接池,以便使用Tomcat的连接池(org.apache.tomcat.jdbc.pool)而不是“Apache Commons DBCP”。

However, I'm getting this error when trying to connect to the DB:

但是,我在尝试连接到数据库时遇到此错误:

javax.servlet.ServletException: java.lang.AbstractMethodError: Method com/mysql/jdbc/PreparedStatement.isClosed()Z is abstract
org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:909)
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:838)
...
...

I've read in other links that normally this is a problem with the MySQL-JDBC driver version, however, I've just updated to the latest Connector/J version (mysql-connector-java-8.0.11.jar) but I'm still getting this error.

我在其他链接中读到通常这是MySQL-JDBC驱动程序版本的问题,但是,我刚刚更新到最新的Connector / J版本(mysql-connector-java-8.0.11.jar)但是我我仍然得到这个错误。

Here's how the connection pool is created:

以下是创建连接池的方法:

First, this goes on the context.xml file in the META-INF directory of my app:

首先,这是在我的应用程序的META-INF目录中的context.xml文件中:

<?xml version="1.0" encoding="UTF-8"?>

<Context>
<Resource
    name="rhwebDB"
    auth="Container"
    type="javax.sql.DataSource"
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    testWhileIdle="true"
    testOnBorrow="true"
    testOnReturn="false"
    validationQuery="SELECT 1"
    validationInterval="30000"
    timeBetweenEvictionRunsMillis="30000"
    maxActive="10"
    minIdle="5"
    maxIdle="10"
    maxWait="10000"
    initialSize="2"
    removeAbandonedTimeout="60"
    removeAbandoned="true"
    logAbandoned="true"
    minEvictableIdleTimeMillis="30000"              
    username="dbUser"
    password="dbPwd"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://127.0.0.1:3306/rhweb2015"/>
</Context>

Then I have a DBUtil.class that all the other libraries use:

然后我有一个所有其他库使用的DBUtil.class:

public class DBUtil {

    static Connection connection = null;
    static {
        try {
            Context context = new InitialContext();
            DataSource ds = (DataSource)context.lookup("java:comp/env/rhwebDB");
            connection = ds.getConnection();
        } catch (NamingException e) {
            System.out.println("DBUtil.NamingException" + e);
        } catch (SQLException e) {
            System.out.println("DBUtil.SQLException" + e);
        }
    }

    public static Connection getConnection() {
        return connection;
    }

    public static synchronized void closeConnection(Connection conn) {
        try {
            if (conn != null && !conn.isClosed())
                conn.close();
        } catch (SQLException sqle) {
            System.out.println("Error closing the connection ! " + sqle);
        }

    }
}

And finally, all the other java libraries use the connection pool like this:

最后,所有其他java库都使用连接池,如下所示:

public boolean someFunction( String myValue ){
    Connection conn = null;
    boolean fRetVal = false;

    String query = "select something from anytable";

    try {
        conn = DBUtil.getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery( query );

        if ( rs.next() )
            fRetVal = true;

        rs.close();
        stmt.close();

    } catch( SQLException ex ) {
            System.out.println(ex);
    }finally{
        DBUtil.closeConnection(conn);
    }

    return fRetVal;
}

Am I missing something? I don't get any errors when Tomcat starts.

我错过了什么吗? Tomcat启动时我没有收到任何错误。

JDK version: 8 (java version "1.8.0_111") Tomcat version: 8.5.8 MySQL Server 5.6

JDK版本:8(java版“1.8.0_111”)Tomcat版本:8.5.8 MySQL Server 5.6

Any help will be really appreciated

任何帮助将非常感激

1 个解决方案

#1


2  

This is all wrong. You are keeping a dog and barking yourself. You can't use static Connections in the first place, and in the second place using a static Connection defeats the entire purpose of using a connection pool. It should be more like this:

这都错了。你养狗和吠叫自己。您不能首先使用静态连接,而在第二个位置使用静态连接会失败使用连接池的整个目的。它应该更像是这样的:

public class DBUtil {

    static DataSource ds;
    static {
        try {
            Context context = new InitialContext();
            ds = (DataSource)context.lookup("java:comp/env/rhwebDB");
        } catch (NamingException e) {
            System.out.println("DBUtil.NamingException" + e);
        } catch (SQLException e) {
            System.out.println("DBUtil.SQLException" + e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

and, using try-with-resources to close everything:

并使用try-with-resources关闭所有内容:

public boolean someFunction( String myValue ){
    boolean fRetVal = false;

    String query = "select something from anytable";

    try (Connection conn = DBUtil.getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery( query )) {
        if ( rs.next() )
            fRetVal = true;
    } catch( SQLException ex ) {
        System.out.println(ex);
    }

    return fRetVal;
}

E&OE

But note that you don't really need the DBUtil class at all. You can inject the DataSource anywhere you need it via an annotation.

但请注意,您根本不需要DBUtil类。您可以通过注释将DataSource注入所需的任何位置。

#1


2  

This is all wrong. You are keeping a dog and barking yourself. You can't use static Connections in the first place, and in the second place using a static Connection defeats the entire purpose of using a connection pool. It should be more like this:

这都错了。你养狗和吠叫自己。您不能首先使用静态连接,而在第二个位置使用静态连接会失败使用连接池的整个目的。它应该更像是这样的:

public class DBUtil {

    static DataSource ds;
    static {
        try {
            Context context = new InitialContext();
            ds = (DataSource)context.lookup("java:comp/env/rhwebDB");
        } catch (NamingException e) {
            System.out.println("DBUtil.NamingException" + e);
        } catch (SQLException e) {
            System.out.println("DBUtil.SQLException" + e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

and, using try-with-resources to close everything:

并使用try-with-resources关闭所有内容:

public boolean someFunction( String myValue ){
    boolean fRetVal = false;

    String query = "select something from anytable";

    try (Connection conn = DBUtil.getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery( query )) {
        if ( rs.next() )
            fRetVal = true;
    } catch( SQLException ex ) {
        System.out.println(ex);
    }

    return fRetVal;
}

E&OE

But note that you don't really need the DBUtil class at all. You can inject the DataSource anywhere you need it via an annotation.

但请注意,您根本不需要DBUtil类。您可以通过注释将DataSource注入所需的任何位置。