Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

java - MySQL Statement Cancellation Timer failed to Stop

What is the reason of the following warning.

WARNING: The web application [TI] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Apr 28, 2016 11:03:25 AM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
WARNING: The web application [TI] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:503)
java.util.TimerThread.mainLoop(Timer.java:526)
java.util.TimerThread.run(Timer.java:505)

It occurs whenever I made change in my code and tomcat restart itself. I am creating mysql connection and I think I am closing it properly.
Here is my code.

@RequestMapping(value = "/file/md5", method = RequestMethod.POST)
public ResponseEntity<?> md5Status(@RequestParam(required = true) String filename) {

    Connection con = SqlUtility.getMysqlConnection(host, port, database,username, password);
    SqlUtility.closeDbInstances(SqlUtility.mysqlConnection);
    SqlUtility.closeDbInstances(con);
    return new ResponseEntity<>(HttpStatus.CONFLICT);
}

Here is the Utility code.

public static Connection mysqlConnection = null;
private static PreparedStatement preparedStatement = null;
private static ResultSet resultSet = null;

public static Connection getMysqlConnection(String host, int port, String database, String username,
        String password) {
    MysqlDataSource mds = null;
    try {
        if (mysqlConnection == null || mysqlConnection.isClosed()) {
            if (database != null && host != null) {
                while (mds == null) {
                    System.out.println("In Loop");
                    mds = new MysqlDataSource();
                    mds.setServerName(host);
                    mds.setPortNumber(port);
                    mds.setDatabaseName(database);
                    mds.setUser(username);
                    mds.setPassword(password);
                    try {
                        mysqlConnection = mds.getConnection();
                    } catch (CommunicationsException e) {
                        System.out.format(
                                "Error occurred while trying to get connection with database [%s]. Are your database host [%s] and port [%s] correct? %n%s%n",
                                database, host, port, e);
                        mds = null;
                        // Had to handle for retrying again and again
                        // This is because your mysql is bind on localhost change it in my.cfg 
                    }
                }
            } else {
                System.out.format(
                        "Error occurred while trying to get connection with database [%s] with username [%s] and password [%s].
 [ATTN] Make sure your DB adapter properties file contains all required attributes. %n",
                        database, username, password);

            }

        }
    } catch (SQLException e) {
        System.out.format(
                "Error occurred while trying to get connection at host [%s] with database [%s] with username [%s] and password [%s] %n%s%n",
                host, database, username, password, e);
        // It might be because of the database privileges which must be grant to access 
    } catch (RuntimeException e) {
        System.out.format("Error occurred while trying to get [%s] Connection %n%s%n", database, e);
    }

    if (mysqlConnection != null)
        System.out.format("[%S] Connection Successfully Created%n", database);
    return mysqlConnection;

}

public static void closeDbInstances(Connection con) {
    System.out.println("Trying to close Database Connection...");
    if (con != null && preparedStatement != null && resultSet != null) {
        try {
            resultSet.close();
            preparedStatement.close();
            con.close();
            System.out.println("Database Connection Closed");
        } catch (SQLException e) {
            System.out.println("Error occurred while trying to close Database connection " + e);
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

(old question but I encountered the same error/warning message) Do you use a jdbc pool with QueryTimeoutInterceptor or call statement.setQueryTimeout(320) function. It invokes an internal mysqljdbc.jar thread to cancel long running queries.

Tomcat hotdeployment does not recognize it so thread is left running behind and keeping a dead webapp context still in RAM.

  <Resource name="jdbc/BSManager" auth="Container" 
    type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    initialSize="2" maxActive="100" maxIdle="10" maxWait="30000"    
    username="myuser" password="mypwd"
    driverClassName="com.mysql.jdbc.Driver" 
    jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor(queryTimeout=320)"
    url="jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&amp;characterEncoding=utf8"
        validationQuery="SELECT 1" removeAbandoned="true" removeAbandonedTimeout="7200"
        testOnBorrow="true" maxAge="1800000"
  />

This warning message The web application [TI] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it happens even if this listener is activated in tomcat/conf/server.xml file. I don't know if dead webapp is released after a query timeout. I have decided not to use a query timeout with MySQL jdbc driver.

  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" 
        classesToInitialize="com.mysql.jdbc.NonRegisteringDriver" />

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...