blob: 2939d9215feac2cf177e358fe14459cf5f5368c7 [file] [log] [blame]
/*
* 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.InstanceNotFoundException;
import javax.management.MBeanRegistration;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.apache.catalina.Globals;
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 MBeanRegistration {
private static Log log = LogFactory.getLog(LifecycleMBeanBase.class);
private static StringManager sm =
StringManager.getManager("org.apache.catalina.util");
/* Cache components of the MBean registration. */
private String domain = null;
private ObjectName oname = null;
protected MBeanServer mserver = null;
/**
* Sub-classes wishing to perform additional initialization should override
* this method, ensuring that super.initInternal() is the first call in the
* overriding method.
*/
@Override
protected void initInternal() throws LifecycleException {
// If oname is not null then registration has already happened via
// preRegister().
if (oname == null) {
mserver = Registry.getRegistry(null, null).getMBeanServer();
oname = register(this, getObjectNameKeyProperties());
}
}
/**
* Sub-classes wishing to perform additional clean-up should override this
* method, ensuring that super.destroyInternal() is the last call in the
* overriding method.
*/
@Override
protected void destroyInternal() throws LifecycleException {
unregister(oname);
}
/**
* Specify the domain under which this component should be registered. Used
* with components that cannot (easily) navigate the component hierarchy to
* determine the correct domain to use.
*/
public final void setDomain(String domain) {
this.domain = domain;
}
/**
* Obtain the domain under which this component will be / has been
* registered.
*/
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();
/**
* Obtain the name under which this component has been registered with JMX.
*/
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 MBeanRegistration} 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 (MalformedObjectNameException e) {
log.warn(sm.getString("lifecycleMBeanBase.registerFail", obj, name),
e);
} 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 MBeanRegistration} 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) {
// If null ObjectName, just return without complaint
if (on == null) {
return;
}
// If the MBeanServer is null, log a warning & return
if (mserver == null) {
log.warn(sm.getString("lifecycleMBeanBase.unregisterNoServer", on));
return;
}
try {
mserver.unregisterMBean(on);
} catch (MBeanRegistrationException e) {
log.warn(sm.getString("lifecycleMBeanBase.unregisterFail", on), e);
} catch (InstanceNotFoundException e) {
log.warn(sm.getString("lifecycleMBeanBase.unregisterFail", on), e);
}
}
/**
* 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
}
/**
* Allows the object to be registered with an alternative
* {@link MBeanServer} and/or {@link ObjectName}.
*/
@Override
public final ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
this.mserver = server;
this.oname = name;
this.domain = name.getDomain();
return oname;
}
}