author | prr |
Mon, 04 Nov 2019 10:01:55 -0800 | |
changeset 59176 | f5adbf111424 |
parent 47216 | 71c04702a3d5 |
child 55994 | 9721e36abeb0 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
43235 | 2 |
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package javax.management; |
|
27 |
||
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
28 |
import com.sun.jmx.defaults.JmxProperties; |
2 | 29 |
import static com.sun.jmx.defaults.JmxProperties.JMX_INITIAL_BUILDER; |
30 |
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; |
|
31 |
import com.sun.jmx.mbeanserver.GetPropertyAction; |
|
32 |
import java.security.AccessController; |
|
33 |
import java.security.Permission; |
|
34 |
import java.util.ArrayList; |
|
43235 | 35 |
import java.lang.System.Logger.Level; |
2 | 36 |
import javax.management.loading.ClassLoaderRepository; |
18206 | 37 |
import sun.reflect.misc.ReflectUtil; |
2 | 38 |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
39 |
|
2 | 40 |
/** |
41 |
* <p>Provides MBean server references. There are no instances of |
|
42 |
* this class.</p> |
|
43 |
* |
|
44 |
* <p>Since JMX 1.2 this class makes it possible to replace the default |
|
45 |
* MBeanServer implementation. This is done using the |
|
46 |
* {@link javax.management.MBeanServerBuilder} class. |
|
47 |
* The class of the initial MBeanServerBuilder to be |
|
48 |
* instantiated can be specified through the |
|
49 |
* <b>javax.management.builder.initial</b> system property. |
|
50 |
* The specified class must be a public subclass of |
|
51 |
* {@link javax.management.MBeanServerBuilder}, and must have a public |
|
52 |
* empty constructor. |
|
53 |
* <p>By default, if no value for that property is specified, an instance of |
|
54 |
* {@link |
|
55 |
* javax.management.MBeanServerBuilder javax.management.MBeanServerBuilder} |
|
56 |
* is created. Otherwise, the MBeanServerFactory attempts to load the |
|
57 |
* specified class using |
|
58 |
* {@link java.lang.Thread#getContextClassLoader() |
|
59 |
* Thread.currentThread().getContextClassLoader()}, or if that is null, |
|
60 |
* {@link java.lang.Class#forName(java.lang.String) Class.forName()}. Then |
|
61 |
* it creates an initial instance of that Class using |
|
62 |
* {@link java.lang.Class#newInstance()}. If any checked exception |
|
63 |
* is raised during this process (e.g. |
|
64 |
* {@link java.lang.ClassNotFoundException}, |
|
65 |
* {@link java.lang.InstantiationException}) the MBeanServerFactory |
|
66 |
* will propagate this exception from within a RuntimeException.</p> |
|
67 |
* |
|
68 |
* <p>The <b>javax.management.builder.initial</b> system property is |
|
69 |
* consulted every time a new MBeanServer needs to be created, and the |
|
70 |
* class pointed to by that property is loaded. If that class is different |
|
71 |
* from that of the current MBeanServerBuilder, then a new MBeanServerBuilder |
|
72 |
* is created. Otherwise, the MBeanServerFactory may create a new |
|
73 |
* MBeanServerBuilder or reuse the current one.</p> |
|
74 |
* |
|
75 |
* <p>If the class pointed to by the property cannot be |
|
76 |
* loaded, or does not correspond to a valid subclass of MBeanServerBuilder |
|
77 |
* then an exception is propagated, and no MBeanServer can be created until |
|
78 |
* the <b>javax.management.builder.initial</b> system property is reset to |
|
79 |
* valid value.</p> |
|
80 |
* |
|
81 |
* <p>The MBeanServerBuilder makes it possible to wrap the MBeanServers |
|
82 |
* returned by the default MBeanServerBuilder implementation, for the purpose |
|
83 |
* of e.g. adding an additional security layer.</p> |
|
84 |
* |
|
85 |
* @since 1.5 |
|
86 |
*/ |
|
87 |
public class MBeanServerFactory { |
|
88 |
||
89 |
/* |
|
90 |
* There are no instances of this class so don't generate the |
|
91 |
* default public constructor. |
|
92 |
*/ |
|
93 |
private MBeanServerFactory() { |
|
94 |
||
95 |
} |
|
96 |
||
97 |
/** |
|
98 |
* The builder that will be used to construct MBeanServers. |
|
99 |
* |
|
100 |
**/ |
|
101 |
private static MBeanServerBuilder builder = null; |
|
102 |
||
103 |
/** |
|
104 |
* Provide a new {@link javax.management.MBeanServerBuilder}. |
|
105 |
* @param builder The new MBeanServerBuilder that will be used to |
|
106 |
* create {@link javax.management.MBeanServer}s. |
|
107 |
* @exception IllegalArgumentException if the given builder is null. |
|
108 |
* |
|
109 |
* @exception SecurityException if there is a SecurityManager and |
|
110 |
* the caller's permissions do not include or imply <code>{@link |
|
111 |
* MBeanServerPermission}("setMBeanServerBuilder")</code>. |
|
112 |
* |
|
113 |
**/ |
|
114 |
// public static synchronized void |
|
115 |
// setMBeanServerBuilder(MBeanServerBuilder builder) { |
|
116 |
// checkPermission("setMBeanServerBuilder"); |
|
117 |
// MBeanServerFactory.builder = builder; |
|
118 |
// } |
|
119 |
||
120 |
/** |
|
121 |
* Get the current {@link javax.management.MBeanServerBuilder}. |
|
122 |
* |
|
123 |
* @return the current {@link javax.management.MBeanServerBuilder}. |
|
124 |
* |
|
125 |
* @exception SecurityException if there is a SecurityManager and |
|
126 |
* the caller's permissions do not include or imply <code>{@link |
|
127 |
* MBeanServerPermission}("getMBeanServerBuilder")</code>. |
|
128 |
* |
|
129 |
**/ |
|
130 |
// public static synchronized MBeanServerBuilder getMBeanServerBuilder() { |
|
131 |
// checkPermission("getMBeanServerBuilder"); |
|
132 |
// return builder; |
|
133 |
// } |
|
134 |
||
135 |
/** |
|
136 |
* Remove internal MBeanServerFactory references to a created |
|
137 |
* MBeanServer. This allows the garbage collector to remove the |
|
138 |
* MBeanServer object. |
|
139 |
* |
|
140 |
* @param mbeanServer the MBeanServer object to remove. |
|
141 |
* |
|
142 |
* @exception java.lang.IllegalArgumentException if |
|
143 |
* <code>mbeanServer</code> was not generated by one of the |
|
144 |
* <code>createMBeanServer</code> methods, or if |
|
145 |
* <code>releaseMBeanServer</code> was already called on it. |
|
146 |
* |
|
147 |
* @exception SecurityException if there is a SecurityManager and |
|
148 |
* the caller's permissions do not include or imply <code>{@link |
|
149 |
* MBeanServerPermission}("releaseMBeanServer")</code>. |
|
150 |
*/ |
|
151 |
public static void releaseMBeanServer(MBeanServer mbeanServer) { |
|
152 |
checkPermission("releaseMBeanServer"); |
|
153 |
||
154 |
removeMBeanServer(mbeanServer); |
|
155 |
} |
|
156 |
||
157 |
/** |
|
158 |
* <p>Return a new object implementing the MBeanServer interface |
|
159 |
* with a standard default domain name. The default domain name |
|
160 |
* is used as the domain part in the ObjectName of MBeans when the |
|
161 |
* domain is specified by the user is null.</p> |
|
162 |
* |
|
163 |
* <p>The standard default domain name is |
|
164 |
* <code>DefaultDomain</code>.</p> |
|
165 |
* |
|
166 |
* <p>The MBeanServer reference is internally kept. This will |
|
167 |
* allow <CODE>findMBeanServer</CODE> to return a reference to |
|
168 |
* this MBeanServer object.</p> |
|
169 |
* |
|
170 |
* <p>This method is equivalent to <code>createMBeanServer(null)</code>. |
|
171 |
* |
|
172 |
* @return the newly created MBeanServer. |
|
173 |
* |
|
174 |
* @exception SecurityException if there is a SecurityManager and the |
|
175 |
* caller's permissions do not include or imply <code>{@link |
|
176 |
* MBeanServerPermission}("createMBeanServer")</code>. |
|
177 |
* |
|
178 |
* @exception JMRuntimeException if the property |
|
179 |
* <code>javax.management.builder.initial</code> exists but the |
|
180 |
* class it names cannot be instantiated through a public |
|
181 |
* no-argument constructor; or if the instantiated builder returns |
|
182 |
* null from its {@link MBeanServerBuilder#newMBeanServerDelegate |
|
183 |
* newMBeanServerDelegate} or {@link |
|
184 |
* MBeanServerBuilder#newMBeanServer newMBeanServer} methods. |
|
185 |
* |
|
186 |
* @exception ClassCastException if the property |
|
187 |
* <code>javax.management.builder.initial</code> exists and can be |
|
188 |
* instantiated but is not assignment compatible with {@link |
|
189 |
* MBeanServerBuilder}. |
|
190 |
*/ |
|
191 |
public static MBeanServer createMBeanServer() { |
|
192 |
return createMBeanServer(null); |
|
193 |
} |
|
194 |
||
195 |
/** |
|
196 |
* <p>Return a new object implementing the {@link MBeanServer} |
|
197 |
* interface with the specified default domain name. The given |
|
198 |
* domain name is used as the domain part in the ObjectName of |
|
199 |
* MBeans when the domain is specified by the user is null.</p> |
|
200 |
* |
|
201 |
* <p>The MBeanServer reference is internally kept. This will |
|
202 |
* allow <CODE>findMBeanServer</CODE> to return a reference to |
|
203 |
* this MBeanServer object.</p> |
|
204 |
* |
|
205 |
* @param domain the default domain name for the created |
|
206 |
* MBeanServer. This is the value that will be returned by {@link |
|
207 |
* MBeanServer#getDefaultDomain}. |
|
208 |
* |
|
209 |
* @return the newly created MBeanServer. |
|
210 |
* |
|
211 |
* @exception SecurityException if there is a SecurityManager and |
|
212 |
* the caller's permissions do not include or imply <code>{@link |
|
213 |
* MBeanServerPermission}("createMBeanServer")</code>. |
|
214 |
* |
|
215 |
* @exception JMRuntimeException if the property |
|
216 |
* <code>javax.management.builder.initial</code> exists but the |
|
217 |
* class it names cannot be instantiated through a public |
|
218 |
* no-argument constructor; or if the instantiated builder returns |
|
219 |
* null from its {@link MBeanServerBuilder#newMBeanServerDelegate |
|
220 |
* newMBeanServerDelegate} or {@link |
|
221 |
* MBeanServerBuilder#newMBeanServer newMBeanServer} methods. |
|
222 |
* |
|
223 |
* @exception ClassCastException if the property |
|
224 |
* <code>javax.management.builder.initial</code> exists and can be |
|
225 |
* instantiated but is not assignment compatible with {@link |
|
226 |
* MBeanServerBuilder}. |
|
227 |
*/ |
|
228 |
public static MBeanServer createMBeanServer(String domain) { |
|
4156 | 229 |
checkPermission("createMBeanServer"); |
2 | 230 |
|
4156 | 231 |
final MBeanServer mBeanServer = newMBeanServer(domain); |
232 |
addMBeanServer(mBeanServer); |
|
233 |
return mBeanServer; |
|
2 | 234 |
} |
235 |
||
236 |
/** |
|
237 |
* <p>Return a new object implementing the MBeanServer interface |
|
238 |
* with a standard default domain name, without keeping an |
|
239 |
* internal reference to this new object. The default domain name |
|
240 |
* is used as the domain part in the ObjectName of MBeans when the |
|
241 |
* domain is specified by the user is null.</p> |
|
242 |
* |
|
243 |
* <p>The standard default domain name is |
|
244 |
* <code>DefaultDomain</code>.</p> |
|
245 |
* |
|
246 |
* <p>No reference is kept. <CODE>findMBeanServer</CODE> will not |
|
247 |
* be able to return a reference to this MBeanServer object, but |
|
248 |
* the garbage collector will be able to remove the MBeanServer |
|
249 |
* object when it is no longer referenced.</p> |
|
250 |
* |
|
251 |
* <p>This method is equivalent to <code>newMBeanServer(null)</code>.</p> |
|
252 |
* |
|
253 |
* @return the newly created MBeanServer. |
|
254 |
* |
|
255 |
* @exception SecurityException if there is a SecurityManager and the |
|
256 |
* caller's permissions do not include or imply <code>{@link |
|
257 |
* MBeanServerPermission}("newMBeanServer")</code>. |
|
258 |
* |
|
259 |
* @exception JMRuntimeException if the property |
|
260 |
* <code>javax.management.builder.initial</code> exists but the |
|
261 |
* class it names cannot be instantiated through a public |
|
262 |
* no-argument constructor; or if the instantiated builder returns |
|
263 |
* null from its {@link MBeanServerBuilder#newMBeanServerDelegate |
|
264 |
* newMBeanServerDelegate} or {@link |
|
265 |
* MBeanServerBuilder#newMBeanServer newMBeanServer} methods. |
|
266 |
* |
|
267 |
* @exception ClassCastException if the property |
|
268 |
* <code>javax.management.builder.initial</code> exists and can be |
|
269 |
* instantiated but is not assignment compatible with {@link |
|
270 |
* MBeanServerBuilder}. |
|
271 |
*/ |
|
272 |
public static MBeanServer newMBeanServer() { |
|
273 |
return newMBeanServer(null); |
|
274 |
} |
|
275 |
||
276 |
/** |
|
277 |
* <p>Return a new object implementing the MBeanServer interface |
|
278 |
* with the specified default domain name, without keeping an |
|
279 |
* internal reference to this new object. The given domain name |
|
280 |
* is used as the domain part in the ObjectName of MBeans when the |
|
281 |
* domain is specified by the user is null.</p> |
|
282 |
* |
|
283 |
* <p>No reference is kept. <CODE>findMBeanServer</CODE> will not |
|
284 |
* be able to return a reference to this MBeanServer object, but |
|
285 |
* the garbage collector will be able to remove the MBeanServer |
|
286 |
* object when it is no longer referenced.</p> |
|
287 |
* |
|
288 |
* @param domain the default domain name for the created |
|
289 |
* MBeanServer. This is the value that will be returned by {@link |
|
290 |
* MBeanServer#getDefaultDomain}. |
|
291 |
* |
|
292 |
* @return the newly created MBeanServer. |
|
293 |
* |
|
294 |
* @exception SecurityException if there is a SecurityManager and the |
|
295 |
* caller's permissions do not include or imply <code>{@link |
|
296 |
* MBeanServerPermission}("newMBeanServer")</code>. |
|
297 |
* |
|
298 |
* @exception JMRuntimeException if the property |
|
299 |
* <code>javax.management.builder.initial</code> exists but the |
|
300 |
* class it names cannot be instantiated through a public |
|
301 |
* no-argument constructor; or if the instantiated builder returns |
|
302 |
* null from its {@link MBeanServerBuilder#newMBeanServerDelegate |
|
303 |
* newMBeanServerDelegate} or {@link |
|
304 |
* MBeanServerBuilder#newMBeanServer newMBeanServer} methods. |
|
305 |
* |
|
306 |
* @exception ClassCastException if the property |
|
307 |
* <code>javax.management.builder.initial</code> exists and can be |
|
308 |
* instantiated but is not assignment compatible with {@link |
|
309 |
* MBeanServerBuilder}. |
|
310 |
*/ |
|
311 |
public static MBeanServer newMBeanServer(String domain) { |
|
312 |
checkPermission("newMBeanServer"); |
|
313 |
||
314 |
// Get the builder. Creates a new one if necessary. |
|
315 |
// |
|
316 |
final MBeanServerBuilder mbsBuilder = getNewMBeanServerBuilder(); |
|
317 |
// Returned value cannot be null. NullPointerException if violated. |
|
318 |
||
319 |
synchronized(mbsBuilder) { |
|
320 |
final MBeanServerDelegate delegate = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
321 |
mbsBuilder.newMBeanServerDelegate(); |
2 | 322 |
if (delegate == null) { |
323 |
final String msg = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
324 |
"MBeanServerBuilder.newMBeanServerDelegate() " + |
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
325 |
"returned null"; |
2 | 326 |
throw new JMRuntimeException(msg); |
327 |
} |
|
328 |
final MBeanServer mbeanServer = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
329 |
mbsBuilder.newMBeanServer(domain,null,delegate); |
2 | 330 |
if (mbeanServer == null) { |
331 |
final String msg = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
332 |
"MBeanServerBuilder.newMBeanServer() returned null"; |
2 | 333 |
throw new JMRuntimeException(msg); |
334 |
} |
|
335 |
return mbeanServer; |
|
336 |
} |
|
337 |
} |
|
338 |
||
339 |
/** |
|
340 |
* <p>Return a list of registered MBeanServer objects. A |
|
341 |
* registered MBeanServer object is one that was created by one of |
|
342 |
* the <code>createMBeanServer</code> methods and not subsequently |
|
343 |
* released with <code>releaseMBeanServer</code>.</p> |
|
344 |
* |
|
345 |
* @param agentId The agent identifier of the MBeanServer to |
|
346 |
* retrieve. If this parameter is null, all registered |
|
347 |
* MBeanServers in this JVM are returned. Otherwise, only |
|
348 |
* MBeanServers whose id is equal to <code>agentId</code> are |
|
349 |
* returned. The id of an MBeanServer is the |
|
350 |
* <code>MBeanServerId</code> attribute of its delegate MBean. |
|
351 |
* |
|
352 |
* @return A list of MBeanServer objects. |
|
353 |
* |
|
354 |
* @exception SecurityException if there is a SecurityManager and the |
|
355 |
* caller's permissions do not include or imply <code>{@link |
|
356 |
* MBeanServerPermission}("findMBeanServer")</code>. |
|
357 |
*/ |
|
358 |
public synchronized static |
|
359 |
ArrayList<MBeanServer> findMBeanServer(String agentId) { |
|
360 |
||
361 |
checkPermission("findMBeanServer"); |
|
362 |
||
363 |
if (agentId == null) |
|
364 |
return new ArrayList<MBeanServer>(mBeanServerList); |
|
365 |
||
366 |
ArrayList<MBeanServer> result = new ArrayList<MBeanServer>(); |
|
367 |
for (MBeanServer mbs : mBeanServerList) { |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
368 |
String name = mBeanServerId(mbs); |
2 | 369 |
if (agentId.equals(name)) |
370 |
result.add(mbs); |
|
371 |
} |
|
372 |
return result; |
|
373 |
} |
|
374 |
||
375 |
/** |
|
376 |
* Return the ClassLoaderRepository used by the given MBeanServer. |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
377 |
* This method is equivalent to {@link |
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
378 |
* MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}. |
2 | 379 |
* @param server The MBeanServer under examination. Since JMX 1.2, |
380 |
* if <code>server</code> is <code>null</code>, the result is a |
|
381 |
* {@link NullPointerException}. This behavior differs from what |
|
382 |
* was implemented in JMX 1.1 - where the possibility to use |
|
383 |
* <code>null</code> was deprecated. |
|
384 |
* @return The Class Loader Repository used by the given MBeanServer. |
|
385 |
* @exception SecurityException if there is a SecurityManager and |
|
386 |
* the caller's permissions do not include or imply <code>{@link |
|
387 |
* MBeanPermission}("getClassLoaderRepository")</code>. |
|
388 |
* |
|
389 |
* @exception NullPointerException if <code>server</code> is null. |
|
390 |
* |
|
391 |
**/ |
|
392 |
public static ClassLoaderRepository getClassLoaderRepository( |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
393 |
MBeanServer server) { |
2 | 394 |
return server.getClassLoaderRepository(); |
395 |
} |
|
396 |
||
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
397 |
private static String mBeanServerId(MBeanServer mbs) { |
2 | 398 |
try { |
399 |
return (String) mbs.getAttribute(MBeanServerDelegate.DELEGATE_NAME, |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
400 |
"MBeanServerId"); |
2 | 401 |
} catch (JMException e) { |
43235 | 402 |
JmxProperties.MISC_LOGGER.log(Level.TRACE, |
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
403 |
"Ignoring exception while getting MBeanServerId: "+e); |
2 | 404 |
return null; |
405 |
} |
|
406 |
} |
|
407 |
||
408 |
private static void checkPermission(String action) |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
409 |
throws SecurityException { |
2 | 410 |
SecurityManager sm = System.getSecurityManager(); |
411 |
if (sm != null) { |
|
412 |
Permission perm = new MBeanServerPermission(action); |
|
413 |
sm.checkPermission(perm); |
|
414 |
} |
|
415 |
} |
|
416 |
||
417 |
private static synchronized void addMBeanServer(MBeanServer mbs) { |
|
418 |
mBeanServerList.add(mbs); |
|
419 |
} |
|
420 |
||
421 |
private static synchronized void removeMBeanServer(MBeanServer mbs) { |
|
422 |
boolean removed = mBeanServerList.remove(mbs); |
|
423 |
if (!removed) { |
|
43235 | 424 |
MBEANSERVER_LOGGER.log(Level.TRACE, |
2 | 425 |
"MBeanServer was not in list!"); |
426 |
throw new IllegalArgumentException("MBeanServer was not in list!"); |
|
427 |
} |
|
428 |
} |
|
429 |
||
430 |
private static final ArrayList<MBeanServer> mBeanServerList = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
431 |
new ArrayList<MBeanServer>(); |
2 | 432 |
|
433 |
/** |
|
434 |
* Load the builder class through the context class loader. |
|
435 |
* @param builderClassName The name of the builder class. |
|
436 |
**/ |
|
1510
e747d3193ef2
6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents:
1247
diff
changeset
|
437 |
private static Class<?> loadBuilderClass(String builderClassName) |
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
438 |
throws ClassNotFoundException { |
2 | 439 |
final ClassLoader loader = |
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
440 |
Thread.currentThread().getContextClassLoader(); |
2 | 441 |
|
442 |
if (loader != null) { |
|
443 |
// Try with context class loader |
|
444 |
return loader.loadClass(builderClassName); |
|
445 |
} |
|
446 |
||
447 |
// No context class loader? Try with Class.forName() |
|
18206 | 448 |
return ReflectUtil.forName(builderClassName); |
2 | 449 |
} |
450 |
||
451 |
/** |
|
452 |
* Creates the initial builder according to the |
|
453 |
* javax.management.builder.initial System property - if specified. |
|
454 |
* If any checked exception needs to be thrown, it is embedded in |
|
455 |
* a JMRuntimeException. |
|
456 |
**/ |
|
1510
e747d3193ef2
6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents:
1247
diff
changeset
|
457 |
private static MBeanServerBuilder newBuilder(Class<?> builderClass) { |
2 | 458 |
try { |
37782
ad8fe7507ecc
6850612: Deprecate Class.newInstance since it violates the checked exception language contract
darcy
parents:
25859
diff
changeset
|
459 |
@SuppressWarnings("deprecation") |
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
460 |
final Object abuilder = builderClass.newInstance(); |
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
461 |
return (MBeanServerBuilder)abuilder; |
2 | 462 |
} catch (RuntimeException x) { |
463 |
throw x; |
|
464 |
} catch (Exception x) { |
|
465 |
final String msg = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
466 |
"Failed to instantiate a MBeanServerBuilder from " + |
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
467 |
builderClass + ": " + x; |
2 | 468 |
throw new JMRuntimeException(msg, x); |
469 |
} |
|
470 |
} |
|
471 |
||
472 |
/** |
|
473 |
* Instantiate a new builder according to the |
|
474 |
* javax.management.builder.initial System property - if needed. |
|
475 |
**/ |
|
476 |
private static synchronized void checkMBeanServerBuilder() { |
|
477 |
try { |
|
478 |
GetPropertyAction act = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
479 |
new GetPropertyAction(JMX_INITIAL_BUILDER); |
2 | 480 |
String builderClassName = AccessController.doPrivileged(act); |
481 |
||
482 |
try { |
|
1510
e747d3193ef2
6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents:
1247
diff
changeset
|
483 |
final Class<?> newBuilderClass; |
2 | 484 |
if (builderClassName == null || builderClassName.length() == 0) |
485 |
newBuilderClass = MBeanServerBuilder.class; |
|
486 |
else |
|
487 |
newBuilderClass = loadBuilderClass(builderClassName); |
|
488 |
||
489 |
// Check whether a new builder needs to be created |
|
490 |
if (builder != null) { |
|
1510
e747d3193ef2
6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents:
1247
diff
changeset
|
491 |
final Class<?> builderClass = builder.getClass(); |
2 | 492 |
if (newBuilderClass == builderClass) |
493 |
return; // no need to create a new builder... |
|
494 |
} |
|
495 |
||
496 |
// Create a new builder |
|
497 |
builder = newBuilder(newBuilderClass); |
|
498 |
} catch (ClassNotFoundException x) { |
|
499 |
final String msg = |
|
1156
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
500 |
"Failed to load MBeanServerBuilder class " + |
bbc2d15aaf7a
5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents:
2
diff
changeset
|
501 |
builderClassName + ": " + x; |
2 | 502 |
throw new JMRuntimeException(msg, x); |
503 |
} |
|
504 |
} catch (RuntimeException x) { |
|
43235 | 505 |
if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { |
2 | 506 |
StringBuilder strb = new StringBuilder() |
507 |
.append("Failed to instantiate MBeanServerBuilder: ").append(x) |
|
508 |
.append("\n\t\tCheck the value of the ") |
|
509 |
.append(JMX_INITIAL_BUILDER).append(" property."); |
|
43235 | 510 |
MBEANSERVER_LOGGER.log(Level.DEBUG, strb::toString); |
2 | 511 |
} |
512 |
throw x; |
|
513 |
} |
|
514 |
} |
|
515 |
||
516 |
/** |
|
517 |
* Get the current {@link javax.management.MBeanServerBuilder}, |
|
518 |
* as specified by the current value of the |
|
519 |
* javax.management.builder.initial property. |
|
520 |
* |
|
521 |
* This method consults the property and instantiates a new builder |
|
522 |
* if needed. |
|
523 |
* |
|
524 |
* @return the new current {@link javax.management.MBeanServerBuilder}. |
|
525 |
* |
|
526 |
* @exception SecurityException if there is a SecurityManager and |
|
527 |
* the caller's permissions do not make it possible to instantiate |
|
528 |
* a new builder. |
|
529 |
* @exception JMRuntimeException if the builder instantiation |
|
530 |
* fails with a checked exception - |
|
531 |
* {@link java.lang.ClassNotFoundException} etc... |
|
532 |
* |
|
533 |
**/ |
|
534 |
private static synchronized MBeanServerBuilder getNewMBeanServerBuilder() { |
|
535 |
checkMBeanServerBuilder(); |
|
536 |
return builder; |
|
537 |
} |
|
538 |
||
539 |
} |