package com.cloudhopper.commons.sql.c3p0; /* * #%L * ch-commons-sql * %% * Copyright (C) 2012 - 2013 Cloudhopper by Twitter * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import com.mchange.v2.c3p0.*; import com.mchange.v2.c3p0.management.*; import com.mchange.v2.log.*; import java.lang.management.*; import javax.management.*; /** * Class copied directly from c3p0 source code from the ActiveManagementCoordinator.java * file. This is an implementation to allow customization of how JMX is used * within the c3p0 library. Those customizations include: * <ul> * <li>Custom JMX domain</li> * <li>Per-DataSource JMX on/off registry</li> * </ul> * @author joelauer */ public class C3P0CustomManagementCoordinator implements ManagementCoordinator { // static defaults -- these will work precisely the first time // and then they'll be able to change while the JVM is running private static String C3P0_JMX_DOMAIN = "com.cloudhopper"; /** * Sets the JMX domain to use for registering the C3P0 registery. This will * work exactly once. It must be set prior to starting any C3P0 instance. * @param domain Such as "com.cloudhopper" */ public static void setJmxDomainOnce(String domain) { C3P0_JMX_DOMAIN = domain; } // MT: thread-safe final static MLogger logger = MLog.getLogger(C3P0CustomManagementCoordinator.class); MBeanServer mbs; String jmxDomain; /** * Creates a new instance of C3P0CustomManagementCoordinator and saves * a copy of what the JMX domain was statically set to -- this is then used * for the lifetime of this object. */ public C3P0CustomManagementCoordinator() throws Exception { this.mbs = ManagementFactory.getPlatformMBeanServer(); this.jmxDomain = C3P0_JMX_DOMAIN; } public void attemptManageC3P0Registry() { try { // create objectname for C3P0 registry ObjectName name = new ObjectName(jmxDomain + ":type=C3P0,name=C3P0Registry"); C3P0RegistryManager mbean = new C3P0RegistryManager(); if (mbs.isRegistered(name)) { if (logger.isLoggable(MLevel.WARNING)) { logger.warning("A C3P0Registry mbean is already registered. " + "This probably means that an application using c3p0 was undeployed, " + "but not all PooledDataSources were closed prior to undeployment. " + "This may lead to resource leaks over time. Please take care to close " + "all PooledDataSources."); } mbs.unregisterMBean(name); } mbs.registerMBean(mbean, name); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to set up C3P0RegistryManager mBean. " + "[c3p0 will still function normally, but management via JMX may not be possible.]", e); } } public void attemptUnmanageC3P0Registry() { try { ObjectName name = new ObjectName(jmxDomain + ":type=C3P0,name=C3P0Registry"); if (mbs.isRegistered(name)) { mbs.unregisterMBean(name); if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "C3P0Registry mbean unregistered."); } else if (logger.isLoggable(MLevel.FINE)) logger.fine("The C3P0Registry mbean was not found in the registry, so could not be unregistered."); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while trying to unregister the C3P0RegistryManager mBean." + e); } } public void attemptManagePooledDataSource(PooledDataSource pds) { String name = getPdsObjectNameStr( pds ); try { //PooledDataSourceManager mbean = new PooledDataSourceManager( pds ); //mbs.registerMBean(mbean, ObjectName.getInstance(name)); //if (logger.isLoggable(MLevel.FINER)) // logger.log(MLevel.FINER, "MBean: " + name + " registered."); // DynamicPooledDataSourceManagerMBean registers itself on construction (and logs its own registration) DynamicPooledDataSourceManagerMBean mbean = new DynamicPooledDataSourceManagerMBean( pds, name, mbs ); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to set up a PooledDataSourceManager mBean. [" + name + "] " + "[c3p0 will still functioning normally, but management via JMX may not be possible.]", e); } } public void attemptUnmanagePooledDataSource(PooledDataSource pds) { String nameStr = getPdsObjectNameStr( pds ); try { ObjectName name = new ObjectName( nameStr ); if (mbs.isRegistered(name)) { mbs.unregisterMBean(name); if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "MBean: " + nameStr + " unregistered."); } else if (logger.isLoggable(MLevel.FINE)) logger.fine("The mbean " + nameStr + " was not found in the registry, so could not be unregistered."); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while unregistering mBean. [" + nameStr + "] " + e); } } private String getPdsObjectNameStr(PooledDataSource pds) { return jmxDomain + ":type=C3P0,name=PooledDataSource[" + pds.getDataSourceName() + "]"; } }