web-dev-qa-db-ja.com

JDBCドライバーはTomcat 7によって強制的に登録解除されました。なぜですか?

Tomcat 7に問題があります。それについての情報を次に示します。

1-このメッセージがあります:

INFO: Reloading Context with name [/WebApp] has started
Oct 04, 2013 12:20:50 PM org.Apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/WebApp] 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.

Oct 04, 2013 12:20:50 PM org.Apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/WebApp] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.
Oct 04, 2013 12:20:51 PM org.Apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/WebApp] is completed

2-アプリケーションをリロードすると、約20時間問題が解決し、再び戻ってきます。

3-Tomcatに約10個のアプリケーションがデプロイされていますが、そのうち2つだけがこのエラーを受け取ります。

4-問題はこれら2つのアプリの物ggingいには存在しませんでしたが、約2週間から現れました。

それではどうすればこれを解決できますか?また、コードに関連していますか?

17
AAH

TomcatでWebアプリケーションを停止すると、開始したスレッドのシャットダウンが試行され、JDBCドライバーなどのリソースの束が閉じられます。この場合、それらを閉じることができますが、自分で行う方が安全です。

ServletContextListenerでこれを行うことができます。私は次のように私のものを実装しました

@WebListener // register it as you wish
public class ContainerContextClosedHandler implements ServletContextListener {
    private static final Logger logger = LoggerFactory.getLogger(ContainerContextClosedHandler.class);

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        // nothing to do
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        Enumeration<Driver> drivers = DriverManager.getDrivers();     

        Driver driver = null;

        // clear drivers
        while(drivers.hasMoreElements()) {
            try {
                driver = drivers.nextElement();
                DriverManager.deregisterDriver(driver);

            } catch (SQLException ex) {
                // deregistration failed, might want to do something, log at the very least
            }
        }

        // MySQL driver leaves around a thread. This static method cleans it up.
        try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            // again failure, not much you can do
        }
    }

}

MySQLは、Tomcatが閉じることができないスレッドを開始します。現在のバージョン(5.1.23以降)では、上記のように、生成されたAbandonedConnectionCleanupThreadを閉じるためにThreadクラスを提供しています。

18

各WebアプリケーションのWEB-INF/libディレクトリにConnector/J JDBCドライバーがある場合、これだけでなく、すべてのWebアプリケーションで同様の問題が発生する可能性があります。

TomcatのJDBC接続プールを使用している場合は、Connector/JドライバーをTomcatのlib/ディレクトリに配置し、すべてのWebアプリケーションから削除する必要があります。独自のアプリケーション内から独自の接続プールを維持している場合、JDBCドライバーがグローバルDriverManagerから登録解除されるように調整する必要があります。さらに良いことに、登録ドライバーの代わりにConnector/Jの非登録ドライバーを使用すれば、Tomcatがこのような種類のリークを心配する必要はありません実際にあなたを保護します

5