Hot Deployment Exhausts the PermGen or Metaspace when the Application Includes Database Drivers

Solution Verified - Updated

Environment

  • JBoss Enterprise Application Platform (EAP)

Issue

  • We're bundling our database driver in our application's WEB-INF/lib directory. After a couple hot deployments of this application, JBoss throws an "OutOfMemoryError: PermGen space".
  • The heap dump shows classloaders are building up. The leaked classloaders trace back to the driver classes stored in the writeDrivers Vector of the java.sql.DriverManager system class.

Resolution

  • Do not package database drivers in your application. Package them at the server level instead.
  • For EAP 5, put the driver in the $EAP_HOME/common/lib dir or $EAP_HOME/server/$PROFILE/lib dir
  • You can refer to How to configure datasource setting in EAP 6 on how to set up the database driver as a global server module on EAP 6.
  • If one needs driver is packaged in ear or war for some reason, it should call java.sql.DriverManager#deregisterDriver method during undeployment time like below.
package org.example.clleak;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.PrintWriter;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collections;

@WebListener
public class DriverDeregisterListener implements ServletContextListener {
    @Override
    public void contextDestroyed(ServletContextEvent event) {
        Collections.list(DriverManager.getDrivers())
                .forEach(DriverDeregisterListener::deregisterDriver);
    }

    private static void deregisterDriver(Driver driver) {
        try {
            DriverManager.deregisterDriver(driver);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Root Cause

  • Since the driver is packaged in the application, it is also using the application's classloader. When the application is shutdown, the driver is not, thus the classloader improperly persists after undeployment.

Diagnostic Steps

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.