KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jmx > support > MBeanRegistrationSupport


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.jmx.support;
18
19 import java.util.HashSet JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import javax.management.InstanceAlreadyExistsException JavaDoc;
24 import javax.management.InstanceNotFoundException JavaDoc;
25 import javax.management.JMException JavaDoc;
26 import javax.management.MBeanServer JavaDoc;
27 import javax.management.ObjectInstance JavaDoc;
28 import javax.management.ObjectName JavaDoc;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33 import org.springframework.core.Constants;
34
35 /**
36  * Provides supporting infrastructure for registering MBeans with an
37  * {@link javax.management.MBeanServer}. The behavior when encountering
38  * an existing MBean at a given {@link ObjectName} is fully configurable
39  * allowing for flexible registration settings.
40  *
41  * <p>All registered MBeans are tracked and can be unregistered by calling
42  * the #{@link #unregisterBeans()} method.
43  *
44  * <p>Sub-classes can receive notifications when an MBean is registered or
45  * unregistered by overriding the {@link #onRegister(ObjectName)} and
46  * {@link #onUnregister(ObjectName)} methods respectively.
47  *
48  * <p>By default, the registration process will fail if attempting to
49  * register an MBean using a {@link javax.management.ObjectName} that is
50  * already used.
51  *
52  * <p>By setting the {@link #setRegistrationBehaviorName(String) registrationBehaviorName}
53  * property to <code>REGISTRATION_IGNORE_EXISTING</code> the registration process
54  * will simply ignore existing MBeans leaving them registered. This is useful in settings
55  * where multiple applications want to share a common MBean in a shared {@link MBeanServer}.
56  *
57  * <p>Setting {@link #setRegistrationBehaviorName(String) registrationBehaviorName} property
58  * to <code>REGISTRATION_REPLACE_EXISTING</code> will cause existing MBeans to be replaced
59  * during registration if necessary. This is useful in situations where you can't guarantee
60  * the state of your {@link MBeanServer}.
61  *
62  * @author Rob Harrop
63  * @author Juergen Hoeller
64  * @since 2.0
65  * @see #setServer
66  * @see #setRegistrationBehaviorName
67  * @see org.springframework.jmx.export.MBeanExporter
68  */

69 public class MBeanRegistrationSupport {
70
71     /**
72      * Constant indicating that registration should fail when
73      * attempting to register an MBean under a name that already exists.
74      * <p>This is the default registration behavior.
75      */

76     public static final int REGISTRATION_FAIL_ON_EXISTING = 0;
77
78     /**
79      * Constant indicating that registration should ignore the affected MBean
80      * when attempting to register an MBean under a name that already exists.
81      */

82     public static final int REGISTRATION_IGNORE_EXISTING = 1;
83
84     /**
85      * Constant indicating that registration should replace the affected MBean
86      * when attempting to register an MBean under a name that already exists.
87      */

88     public static final int REGISTRATION_REPLACE_EXISTING = 2;
89
90
91     /**
92      * Constants for this class.
93      */

94     private static final Constants constants = new Constants(MBeanRegistrationSupport.class);
95
96     /**
97      * <code>Log</code> instance for this class.
98      */

99     protected final Log logger = LogFactory.getLog(getClass());
100
101     /**
102      * The <code>MBeanServer</code> instance being used to register beans.
103      */

104     protected MBeanServer JavaDoc server;
105
106     /**
107      * The beans that have been registered by this exporter.
108      */

109     protected Set JavaDoc registeredBeans = new HashSet JavaDoc();
110
111     /**
112      * The action take when registering an MBean and finding that it already exists.
113      * By default an exception is raised.
114      */

115     private int registrationBehavior = REGISTRATION_FAIL_ON_EXISTING;
116
117
118     /**
119      * Specify the <code>MBeanServer</code> instance with which all beans should
120      * be registered. The <code>MBeanExporter</code> will attempt to locate an
121      * existing <code>MBeanServer</code> if none is supplied.
122      */

123     public void setServer(MBeanServer JavaDoc server) {
124         this.server = server;
125     }
126
127     /**
128      * Set the registration behavior by the name of the corresponding constant,
129      * e.g. "REGISTRATION_IGNORE_EXISTING".
130      * @see #setRegistrationBehavior
131      * @see #REGISTRATION_FAIL_ON_EXISTING
132      * @see #REGISTRATION_IGNORE_EXISTING
133      * @see #REGISTRATION_REPLACE_EXISTING
134      */

135     public void setRegistrationBehaviorName(String JavaDoc registrationBehavior) {
136         setRegistrationBehavior(constants.asNumber(registrationBehavior).intValue());
137     }
138
139     /**
140      * Specify what action should be taken when attempting to register an MBean
141      * under an {@link javax.management.ObjectName} that already exists.
142      * <p>Default is REGISTRATION_FAIL_ON_EXISTING.
143      * @see #setRegistrationBehaviorName(String)
144      * @see #REGISTRATION_FAIL_ON_EXISTING
145      * @see #REGISTRATION_IGNORE_EXISTING
146      * @see #REGISTRATION_REPLACE_EXISTING
147      */

148     public void setRegistrationBehavior(int registrationBehavior) {
149         this.registrationBehavior = registrationBehavior;
150     }
151
152
153     /**
154      * Actually register the MBean with the server. The behavior when encountering
155      * an existing MBean can be configured using the {@link #setRegistrationBehavior(int)}
156      * and {@link #setRegistrationBehaviorName(String)} methods.
157      * @throws JMException if the registration failed
158      */

159     protected void doRegister(Object JavaDoc mbean, ObjectName JavaDoc objectName) throws JMException JavaDoc {
160         ObjectInstance JavaDoc registeredBean = null;
161         try {
162             registeredBean = this.server.registerMBean(mbean, objectName);
163         }
164         catch (InstanceAlreadyExistsException JavaDoc ex) {
165             if (this.registrationBehavior == REGISTRATION_IGNORE_EXISTING) {
166                 if (logger.isDebugEnabled()) {
167                     logger.debug("Ignoring existing MBean at [" + objectName + "]");
168                 }
169             }
170             else if (this.registrationBehavior == REGISTRATION_REPLACE_EXISTING) {
171                 try {
172                     if (logger.isDebugEnabled()) {
173                         logger.debug("Replacing existing MBean at [" + objectName + "]");
174                     }
175                     this.server.unregisterMBean(objectName);
176                     registeredBean = this.server.registerMBean(mbean, objectName);
177                 }
178                 catch (InstanceNotFoundException JavaDoc ex2) {
179                     logger.error("Unable to replace existing MBean at [" + objectName + "]", ex2);
180                     throw ex;
181                 }
182             }
183             else {
184                 throw ex;
185             }
186         }
187
188         // Track registration and notify listeners.
189
ObjectName JavaDoc actualObjectName = (registeredBean != null ? registeredBean.getObjectName() : null);
190         if (actualObjectName == null) {
191             actualObjectName = objectName;
192         }
193         this.registeredBeans.add(actualObjectName);
194         onRegister(actualObjectName);
195     }
196
197     /**
198      * Unregisters all beans that have been registered by an instance of this class.
199      */

200     protected void unregisterBeans() {
201         for (Iterator JavaDoc it = this.registeredBeans.iterator(); it.hasNext();) {
202             ObjectName JavaDoc objectName = (ObjectName JavaDoc) it.next();
203             try {
204                 // MBean might already have been unregistered by an external process.
205
if (this.server.isRegistered(objectName)) {
206                     this.server.unregisterMBean(objectName);
207                     onUnregister(objectName);
208                 }
209                 else {
210                     if (logger.isWarnEnabled()) {
211                         logger.warn("Could not unregister MBean [" + objectName + "] as said MBean " +
212                                 "is not registered (perhaps already unregistered by an external process)");
213                     }
214                 }
215             }
216             catch (JMException JavaDoc ex) {
217                 if (logger.isErrorEnabled()) {
218                     logger.error("Could not unregister MBean [" + objectName + "]", ex);
219                 }
220             }
221         }
222         this.registeredBeans.clear();
223     }
224
225
226     /**
227      * Called when an MBean is registered under the given {@link ObjectName}. Allows
228      * subclasses to perform additional processing when an MBean is registered.
229      * @param objectName the {@link ObjectName} of the MBean that was registered.
230      */

231     protected void onRegister(ObjectName JavaDoc objectName) {
232     }
233
234     /**
235      * Called when an MBean is unregistered under the given {@link ObjectName}. Allows
236      * subclasses to perform additional processing when an MBean is unregistered.
237      * @param objectName the {@link ObjectName} of the MBean that was unregistered.
238      */

239     protected void onUnregister(ObjectName JavaDoc objectName) {
240     }
241
242 }
243
Popular Tags