MBean registration happens in a fully synchronized fashion for consistent results
Issue: SPR-11002
This commit is contained in:
parent
1b4e02b178
commit
8d6d6be39a
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.jmx.support;
|
package org.springframework.jmx.support;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.management.InstanceAlreadyExistsException;
|
import javax.management.InstanceAlreadyExistsException;
|
||||||
|
@ -113,7 +112,7 @@ public class MBeanRegistrationSupport {
|
||||||
/**
|
/**
|
||||||
* The beans that have been registered by this exporter.
|
* The beans that have been registered by this exporter.
|
||||||
*/
|
*/
|
||||||
private final Set<ObjectName> registeredBeans = Collections.synchronizedSet(new LinkedHashSet<ObjectName>());
|
private final Set<ObjectName> registeredBeans = new LinkedHashSet<ObjectName>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The policy used when registering an MBean and finding that it already exists.
|
* The policy used when registering an MBean and finding that it already exists.
|
||||||
|
@ -188,40 +187,45 @@ public class MBeanRegistrationSupport {
|
||||||
* @throws JMException if the registration failed
|
* @throws JMException if the registration failed
|
||||||
*/
|
*/
|
||||||
protected void doRegister(Object mbean, ObjectName objectName) throws JMException {
|
protected void doRegister(Object mbean, ObjectName objectName) throws JMException {
|
||||||
ObjectInstance registeredBean = null;
|
ObjectName actualObjectName;
|
||||||
try {
|
|
||||||
registeredBean = this.server.registerMBean(mbean, objectName);
|
synchronized (this.registeredBeans) {
|
||||||
}
|
ObjectInstance registeredBean = null;
|
||||||
catch (InstanceAlreadyExistsException ex) {
|
try {
|
||||||
if (this.registrationPolicy == RegistrationPolicy.IGNORE_EXISTING) {
|
registeredBean = this.server.registerMBean(mbean, objectName);
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Ignoring existing MBean at [" + objectName + "]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (this.registrationPolicy == RegistrationPolicy.REPLACE_EXISTING) {
|
catch (InstanceAlreadyExistsException ex) {
|
||||||
try {
|
if (this.registrationPolicy == RegistrationPolicy.IGNORE_EXISTING) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Replacing existing MBean at [" + objectName + "]");
|
logger.debug("Ignoring existing MBean at [" + objectName + "]");
|
||||||
}
|
}
|
||||||
this.server.unregisterMBean(objectName);
|
|
||||||
registeredBean = this.server.registerMBean(mbean, objectName);
|
|
||||||
}
|
}
|
||||||
catch (InstanceNotFoundException ex2) {
|
else if (this.registrationPolicy == RegistrationPolicy.REPLACE_EXISTING) {
|
||||||
logger.error("Unable to replace existing MBean at [" + objectName + "]", ex2);
|
try {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Replacing existing MBean at [" + objectName + "]");
|
||||||
|
}
|
||||||
|
this.server.unregisterMBean(objectName);
|
||||||
|
registeredBean = this.server.registerMBean(mbean, objectName);
|
||||||
|
}
|
||||||
|
catch (InstanceNotFoundException ex2) {
|
||||||
|
logger.error("Unable to replace existing MBean at [" + objectName + "]", ex2);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw ex;
|
// Track registration and notify listeners.
|
||||||
|
actualObjectName = (registeredBean != null ? registeredBean.getObjectName() : null);
|
||||||
|
if (actualObjectName == null) {
|
||||||
|
actualObjectName = objectName;
|
||||||
}
|
}
|
||||||
|
this.registeredBeans.add(actualObjectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track registration and notify listeners.
|
|
||||||
ObjectName actualObjectName = (registeredBean != null ? registeredBean.getObjectName() : null);
|
|
||||||
if (actualObjectName == null) {
|
|
||||||
actualObjectName = objectName;
|
|
||||||
}
|
|
||||||
this.registeredBeans.add(actualObjectName);
|
|
||||||
onRegister(actualObjectName, mbean);
|
onRegister(actualObjectName, mbean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +233,11 @@ public class MBeanRegistrationSupport {
|
||||||
* Unregisters all beans that have been registered by an instance of this class.
|
* Unregisters all beans that have been registered by an instance of this class.
|
||||||
*/
|
*/
|
||||||
protected void unregisterBeans() {
|
protected void unregisterBeans() {
|
||||||
for (ObjectName objectName : new LinkedHashSet<ObjectName>(this.registeredBeans)) {
|
Set<ObjectName> snapshot;
|
||||||
|
synchronized (this.registeredBeans) {
|
||||||
|
snapshot = new LinkedHashSet<ObjectName>(this.registeredBeans);
|
||||||
|
}
|
||||||
|
for (ObjectName objectName : snapshot) {
|
||||||
doUnregister(objectName);
|
doUnregister(objectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,32 +247,43 @@ public class MBeanRegistrationSupport {
|
||||||
* @param objectName the suggested ObjectName for the MBean
|
* @param objectName the suggested ObjectName for the MBean
|
||||||
*/
|
*/
|
||||||
protected void doUnregister(ObjectName objectName) {
|
protected void doUnregister(ObjectName objectName) {
|
||||||
try {
|
boolean actuallyUnregistered = false;
|
||||||
// MBean might already have been unregistered by an external process.
|
|
||||||
if (this.server.isRegistered(objectName)) {
|
synchronized (this.registeredBeans) {
|
||||||
this.server.unregisterMBean(objectName);
|
if (this.registeredBeans.remove(objectName)) {
|
||||||
onUnregister(objectName);
|
try {
|
||||||
}
|
// MBean might already have been unregistered by an external process
|
||||||
else {
|
if (this.server.isRegistered(objectName)) {
|
||||||
if (logger.isWarnEnabled()) {
|
this.server.unregisterMBean(objectName);
|
||||||
logger.warn("Could not unregister MBean [" + objectName + "] as said MBean " +
|
actuallyUnregistered = true;
|
||||||
"is not registered (perhaps already unregistered by an external process)");
|
}
|
||||||
|
else {
|
||||||
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("Could not unregister MBean [" + objectName + "] as said MBean " +
|
||||||
|
"is not registered (perhaps already unregistered by an external process)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JMException ex) {
|
||||||
|
if (logger.isErrorEnabled()) {
|
||||||
|
logger.error("Could not unregister MBean [" + objectName + "]", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (JMException ex) {
|
|
||||||
if (logger.isErrorEnabled()) {
|
if (actuallyUnregistered) {
|
||||||
logger.error("Could not unregister MBean [" + objectName + "]", ex);
|
onUnregister(objectName);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.registeredBeans.remove(objectName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@link ObjectName ObjectNames} of all registered beans.
|
* Return the {@link ObjectName ObjectNames} of all registered beans.
|
||||||
*/
|
*/
|
||||||
protected final ObjectName[] getRegisteredObjectNames() {
|
protected final ObjectName[] getRegisteredObjectNames() {
|
||||||
return this.registeredBeans.toArray(new ObjectName[this.registeredBeans.size()]);
|
synchronized (this.registeredBeans) {
|
||||||
|
return this.registeredBeans.toArray(new ObjectName[this.registeredBeans.size()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue