LifecycleMBeanBase.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.catalina.util;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.catalina.Globals;
import org.apache.catalina.JmxEnabled;
import org.apache.catalina.LifecycleException;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.res.StringManager;
public abstract class LifecycleMBeanBase extends LifecycleBase implements JmxEnabled {
private static final Log log = LogFactory.getLog(LifecycleMBeanBase.class);
private static final StringManager sm = StringManager.getManager("org.apache.catalina.util");
/* Cache components of the MBean registration. */
private String domain = null;
private ObjectName oname = null;
@Override
protected void initInternal() throws LifecycleException {
// If oname is not null then registration has already happened via
// preRegister().
if (oname == null) {
oname = register(this, getObjectNameKeyProperties());
}
}
@Override
protected void destroyInternal() throws LifecycleException {
unregister(oname);
}
@Override
public final void setDomain(String domain) {
this.domain = domain;
}
@Override
public final String getDomain() {
if (domain == null) {
domain = getDomainInternal();
}
if (domain == null) {
domain = Globals.DEFAULT_MBEAN_DOMAIN;
}
return domain;
}
/**
* Method implemented by sub-classes to identify the domain in which MBeans should be registered.
*
* @return The name of the domain to use to register MBeans.
*/
protected abstract String getDomainInternal();
@Override
public final ObjectName getObjectName() {
return oname;
}
/**
* Allow sub-classes to specify the key properties component of the {@link ObjectName} that will be used to register
* this component.
*
* @return The string representation of the key properties component of the desired {@link ObjectName}
*/
protected abstract String getObjectNameKeyProperties();
/**
* Utility method to enable sub-classes to easily register additional components that don't implement
* {@link JmxEnabled} with an MBean server. <br>
* Note: This method should only be used once {@link #initInternal()} has been called and before
* {@link #destroyInternal()} has been called.
*
* @param obj The object the register
* @param objectNameKeyProperties The key properties component of the object name to use to register the object
*
* @return The name used to register the object
*/
protected final ObjectName register(Object obj, String objectNameKeyProperties) {
// Construct an object name with the right domain
StringBuilder name = new StringBuilder(getDomain());
name.append(':');
name.append(objectNameKeyProperties);
ObjectName on = null;
try {
on = new ObjectName(name.toString());
Registry.getRegistry(null, null).registerComponent(obj, on, null);
} catch (Exception e) {
log.warn(sm.getString("lifecycleMBeanBase.registerFail", obj, name), e);
}
return on;
}
/**
* Utility method to enable sub-classes to easily unregister additional components that don't implement
* {@link JmxEnabled} with an MBean server. <br>
* Note: This method should only be used once {@link #initInternal()} has been called and before
* {@link #destroyInternal()} has been called.
*
* @param objectNameKeyProperties The key properties component of the object name to use to unregister the object
*/
protected final void unregister(String objectNameKeyProperties) {
// Construct an object name with the right domain
StringBuilder name = new StringBuilder(getDomain());
name.append(':');
name.append(objectNameKeyProperties);
Registry.getRegistry(null, null).unregisterComponent(name.toString());
}
/**
* Utility method to enable sub-classes to easily unregister additional components that don't implement
* {@link JmxEnabled} with an MBean server. <br>
* Note: This method should only be used once {@link #initInternal()} has been called and before
* {@link #destroyInternal()} has been called.
*
* @param on The name of the component to unregister
*/
protected final void unregister(ObjectName on) {
Registry.getRegistry(null, null).unregisterComponent(on);
}
/**
* Not used - NOOP.
*/
@Override
public final void postDeregister() {
// NOOP
}
/**
* Not used - NOOP.
*/
@Override
public final void postRegister(Boolean registrationDone) {
// NOOP
}
/**
* Not used - NOOP.
*/
@Override
public final void preDeregister() throws Exception {
// NOOP
}
@Override
public final ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
this.oname = name;
this.domain = name.getDomain().intern();
return oname;
}
}