/* * #%L * P6Spy * %% * Copyright (C) 2013 P6Spy * %% * 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% */ package com.p6spy.engine.spy; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.Collection; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javax.management.StandardMBean; public class P6MBeansRegistry { private final Collection<ObjectName> mBeans = new ArrayList<ObjectName>(); public static final String PACKAGE_NAME = "com.p6spy"; public void registerMBeans(Collection<P6LoadableOptions> allOptions) throws MBeanRegistrationException, InstanceNotFoundException, MalformedObjectNameException, NotCompliantMBeanException { boolean jmx = true; String jmxPrefix = ""; for (P6LoadableOptions options : allOptions) { if (options instanceof P6SpyOptions) { jmx = ((P6SpyOptions) options).getJmx(); jmxPrefix = ((P6SpyOptions) options).getJmxPrefix(); break; } } if (!jmx) { return; } // unreg possible conflicting ones first unregisterAllMBeans(jmxPrefix); // reg all for (P6LoadableOptions options : allOptions) { try { registerMBean(options, jmxPrefix); } catch (InstanceAlreadyExistsException e) { // sounds like someone registered beans already (before we had a chance to do so) // so let's just make things consistent and re-register again registerMBeans(allOptions); } } } protected void registerMBean(P6LoadableOptions mBean, String jmxPrefix) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException { checkMBean(mBean); final ObjectName mBeanObjectName = getObjectName(mBean, jmxPrefix); ManagementFactory.getPlatformMBeanServer().registerMBean(mBean, mBeanObjectName); mBeans.add(mBeanObjectName); } public void unregisterAllMBeans(String jmxPrefix) throws MBeanRegistrationException, MalformedObjectNameException { // those we have reference to final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); for (ObjectName mBeanObjectName : mBeans) { try { mbs.unregisterMBean(mBeanObjectName); } catch (InstanceNotFoundException e) { // this just means someone unregistered our beans already // but we're OK with that and it can't cause failure } } mBeans.clear(); // to prevent naming conflicts: let's unreg also possible leftovers (with the same prefix) for (ObjectName objectName : mbs.queryNames(new ObjectName(getPackageName(jmxPrefix) + ":name=com.p6spy.*"), null)) { try { mbs.unregisterMBean(objectName); } catch (InstanceNotFoundException e) { // this just means someone unregistered the bean earlier than us // (quite unprobable, but parallel unreg could happen) // but we're OK with that and it can't cause failure } } } private void checkMBean(P6LoadableOptions mBean) { if (null == mBean) { throw new IllegalArgumentException("mBean is null!"); } if (!(mBean instanceof StandardMBean)) { throw new IllegalArgumentException( "mBean has to be instance of the StandardMBean class! But is not: " + mBean); } } protected ObjectName getObjectName(P6LoadableOptions mBean, String jmxPrefix) throws MalformedObjectNameException { return new ObjectName(getPackageName(jmxPrefix) + ":name=" + mBean.getClass().getName()); } protected static String getPackageName(String jmxPrefix) { return PACKAGE_NAME + (null == jmxPrefix || jmxPrefix.isEmpty() ? "" : "." + jmxPrefix); } }