, . c3p0 + tomcat 8, , , .
@Override
public void contextDestroyed(@NotNull ServletContextEvent arg0) {
super.contextDestroyed(arg0);
C3P0Registry.getNumPooledDataSources();
Iterator<?> it = C3P0Registry.getPooledDataSources().iterator();
while (it.hasNext()) {
try {
PooledDataSource dataSource = (PooledDataSource) it.next();
dataSource.close();
} catch (Exception e) {
log.error("Error when closing connections ...", e);
}
}
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
log.info(String.format("Unregistering jdbc driver: %s", driver));
} catch (SQLException e) {
log.error(
String.format("Error deregistering driver %s", driver),
e);
}
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread th : threadSet) {
if (th.isDaemon()) {
try {
if (th.getName().equals(
"Resource Destroyer in BasicResourcePool.close()")) {
th.join();
}
} catch (Exception ex) {
log.info("Shutdown waiting was interrupted ...");
}
}
}
immolate();
}
private int immolate() {
int count = 0;
try {
final Field threadLocalsField = Thread.class
.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
final Field inheritableThreadLocalsField = Thread.class
.getDeclaredField("inheritableThreadLocals");
inheritableThreadLocalsField.setAccessible(true);
for (final Thread thread : Thread.getAllStackTraces().keySet()) {
count += clear(threadLocalsField.get(thread));
count += clear(inheritableThreadLocalsField.get(thread));
}
log.info("Immolated " + count + " values in ThreadLocals");
} catch (Exception e) {
log.error("ThreadLocalImmolater.immolate()", e);
}
return count;
}
private int clear(@NotNull final Object threadLocalMap) throws Exception {
if (threadLocalMap == null) {
return 0;
}
int count = 0;
final Field tableField = threadLocalMap.getClass().getDeclaredField(
"table");
tableField.setAccessible(true);
final Object table = tableField.get(threadLocalMap);
for (int i = 0, length = Array.getLength(table); i < length; ++i) {
final Object entry = Array.get(table, i);
if (entry != null) {
final Object threadLocal = ((WeakReference<?>) entry).get();
if (threadLocal != null) {
log(i, threadLocal);
Array.set(table, i, null);
++count;
}
}
}
return count;
}