1 29 30 package com.caucho.jmx; 31 32 import com.caucho.log.Log; 33 import com.caucho.util.Alarm; 34 import com.caucho.util.CharBuffer; 35 import com.caucho.util.L10N; 36 37 import javax.management.*; 38 import java.lang.reflect.Method ; 39 import java.util.ArrayList ; 40 import java.util.Iterator ; 41 import java.util.LinkedHashMap ; 42 import java.util.Map ; 43 import java.util.Set ; 44 import java.util.TimerTask ; 45 import java.util.logging.Level ; 46 import java.util.logging.Logger ; 47 48 51 public class Jmx { 52 private static final L10N L = new L10N(Jmx.class); 53 private static final Logger log = Log.open(Jmx.class); 54 55 private static EnvironmentMBeanServer _mbeanServer; 56 private static MBeanServer _globalMBeanServer; 57 58 61 static void setMBeanServer(EnvironmentMBeanServer server) 62 { 63 _mbeanServer = server; 64 } 65 66 69 public static MBeanServer getContextMBeanServer() 70 { 71 if (_mbeanServer == null) 72 _mbeanServer = (EnvironmentMBeanServer) EnvironmentMBeanServerBuilder.getGlobal("resin"); 73 74 return _mbeanServer; 75 } 76 77 80 public static MBeanServer getGlobalMBeanServer() 81 { 82 if (_globalMBeanServer == null) { 83 getContextMBeanServer(); 84 85 ClassLoader systemLoader = ClassLoader.getSystemClassLoader(); 86 _globalMBeanServer = new GlobalMBeanServer(systemLoader); 87 } 88 89 return _globalMBeanServer; 90 } 91 92 95 public static AbstractMBeanServer getMBeanServer() 96 { 97 return _mbeanServer; 98 } 99 100 103 public static LinkedHashMap <String ,String > copyContextProperties() 104 { 105 AbstractMBeanServer mbeanServer = getMBeanServer(); 106 107 if (mbeanServer != null) 108 return mbeanServer.getContext().copyProperties(); 109 else 110 return new LinkedHashMap <String ,String >(); 111 } 112 113 116 public static LinkedHashMap <String ,String > 117 copyContextProperties(ClassLoader loader) 118 { 119 AbstractMBeanServer mbeanServer = getMBeanServer(); 120 121 if (mbeanServer != null) 122 return mbeanServer.getContext(loader).copyProperties(); 123 else 124 return new LinkedHashMap <String ,String >(); 125 } 126 127 130 public static void setContextProperties(Map <String ,String > properties) 131 { 132 AbstractMBeanServer mbeanServer = getMBeanServer(); 133 134 if (mbeanServer != null) 135 mbeanServer.getContext().setProperties(properties); 136 } 137 138 141 public static void setContextProperties(Map <String ,String > properties, 142 ClassLoader loader) 143 { 144 AbstractMBeanServer mbeanServer = getMBeanServer(); 145 146 if (mbeanServer != null) 147 mbeanServer.getContext(loader).setProperties(properties); 148 } 149 150 158 public static ObjectInstance register(Object object, String name) 159 throws InstanceAlreadyExistsException, 160 MBeanRegistrationException, MalformedObjectNameException, 161 NotCompliantMBeanException 162 { 163 if (name.indexOf(':') < 0) { 164 Map <String ,String > props = parseProperties(name); 165 166 if (props.get("type") == null) { 167 String type = object.getClass().getName(); 168 int p = type.lastIndexOf('.'); 169 if (p > 0) 170 type = type.substring(p + 1); 171 172 props.put("type", type); 173 } 174 175 ObjectName objectName = getObjectName("resin", props); 176 177 return register(object, objectName); 178 } 179 else 180 return register(object, new ObjectName(name)); 181 182 } 183 184 192 public static ObjectInstance register(Object object, 193 Map <String ,String > properties) 194 throws InstanceAlreadyExistsException, 195 MBeanRegistrationException, MalformedObjectNameException, 196 NotCompliantMBeanException 197 { 198 Map <String ,String > props = copyContextProperties(); 199 props.putAll(properties); 200 201 return register(object, getObjectName("resin", props)); 202 } 203 204 212 public static ObjectInstance register(Object object, ObjectName name) 213 throws InstanceAlreadyExistsException, 214 MBeanRegistrationException, 215 NotCompliantMBeanException 216 { 217 return getMBeanServer().registerMBean(createMBean(object, name), name); 218 } 219 220 228 public static ObjectInstance register(Object object, ObjectName name, 229 ClassLoader loader) 230 throws InstanceAlreadyExistsException, 231 MBeanRegistrationException, 232 NotCompliantMBeanException 233 { 234 Thread thread = Thread.currentThread(); 235 ClassLoader oldLoader = thread.getContextClassLoader(); 236 237 try { 238 thread.setContextClassLoader(loader); 239 240 AbstractMBeanServer mbeanServer = getMBeanServer(); 241 242 if (mbeanServer != null) 243 return mbeanServer.registerMBean(createMBean(object, name), name); 244 else 245 return null; 246 } finally { 247 thread.setContextClassLoader(oldLoader); 248 } 249 } 250 251 254 private static DynamicMBean createMBean(Object obj, ObjectName name) 255 throws NotCompliantMBeanException 256 { 257 if (obj == null) 258 throw new NotCompliantMBeanException(L.l("{0} mbean is null", name)); 259 else if (obj instanceof DynamicMBean) 260 return (DynamicMBean) obj; 261 262 Class ifc = getMBeanInterface(obj.getClass()); 263 264 if (ifc == null) 265 throw new NotCompliantMBeanException(L.l("{0} mbean has no MBean interface", name)); 266 267 return new IntrospectionMBean(obj, ifc); 268 } 269 270 273 private static Class getMBeanInterface(Class cl) 274 { 275 for (; cl != null; cl = cl.getSuperclass()) { 276 Class []interfaces = cl.getInterfaces(); 277 278 for (int i = 0; i < interfaces.length; i++) { 279 Class ifc = interfaces[i]; 280 281 if (ifc.getName().endsWith("MBean") || 282 ifc.getName().endsWith("MXBean")) 283 return ifc; 284 } 285 } 286 287 return null; 288 } 289 290 295 public static void unregister(ObjectName name) 296 throws MBeanRegistrationException, 297 InstanceNotFoundException 298 { 299 getMBeanServer().unregisterMBean(name); 300 } 301 302 307 public static void unregister(ObjectName name, ClassLoader loader) 308 throws MBeanRegistrationException, 309 InstanceNotFoundException 310 { 311 Thread thread = Thread.currentThread(); 312 ClassLoader oldLoader = thread.getContextClassLoader(); 313 314 try { 315 thread.setContextClassLoader(loader); 316 317 getMBeanServer().unregisterMBean(name); 318 } finally { 319 thread.setContextClassLoader(oldLoader); 320 } 321 } 322 323 332 public static ObjectInstance register(Object object, 333 String name, 334 Class api) 335 throws InstanceAlreadyExistsException, 336 MBeanRegistrationException, 337 MalformedObjectNameException, 338 NotCompliantMBeanException 339 { 340 return register(object, new ObjectName(name), api); 341 } 342 343 352 public static ObjectInstance register(Object object, 353 ObjectName name, 354 Class api) 355 throws InstanceAlreadyExistsException, 356 MBeanRegistrationException, MalformedObjectNameException, 357 NotCompliantMBeanException 358 { 359 IntrospectionMBean mbean = new IntrospectionMBean(object, api); 360 361 return getMBeanServer().registerMBean(mbean, name); 362 } 363 364 372 public static void unregister(String name) 373 throws InstanceNotFoundException, 374 MalformedObjectNameException, 375 MBeanRegistrationException 376 377 { 378 ObjectName objectName = getObjectName(name); 379 380 getMBeanServer().unregisterMBean(objectName); 381 } 383 384 387 public static ObjectName getObjectName(String name) 388 throws MalformedObjectNameException 389 { 390 return getMBeanServer().getContext().getObjectName(name); 391 } 392 393 396 public static LinkedHashMap <String ,String > parseProperties(String name) 397 { 398 LinkedHashMap <String ,String > map = new LinkedHashMap <String ,String >(); 399 400 parseProperties(map, name); 401 402 return map; 403 } 404 405 408 public static void parseProperties(Map <String ,String > properties, 409 String name) 410 { 411 parseProperties(properties, name, 0); 412 } 413 414 417 private static void 418 parseProperties(Map <String ,String > properties, String name, int i) 419 { 420 CharBuffer cb = CharBuffer.allocate(); 421 422 int len = name.length(); 423 424 while (i < len) { 425 for (; i < len && Character.isWhitespace(name.charAt(i)); i++) { 426 } 427 428 cb.clear(); 429 430 int ch; 431 for (; i < len && (ch = name.charAt(i)) != '=' && ch != ',' && 432 ! Character.isWhitespace((char) ch); i++) { 433 cb.append((char) ch); 434 } 435 436 String key = cb.toString(); 437 438 if (key.length() == 0) { 439 throw new IllegalArgumentException (L.l("`{0}' is an illegal name syntax.", 440 name)); 441 } 442 443 for (; i < len && Character.isWhitespace(name.charAt(i)); i++) { 444 } 445 446 if (len <= i || (ch = name.charAt(i)) == ',') { 447 properties.put(key, ""); 448 } 449 else if (ch == '=') { 450 for (i++; i < len && Character.isWhitespace(name.charAt(i)); i++) { 451 } 452 453 if (len <= i || (ch = name.charAt(i)) == ',') { 454 properties.put(key, ""); 455 } 456 else if (ch == '"' || ch == '\'') { 457 int end = ch; 458 cb.clear(); 459 460 for (i++; i < len && (ch = name.charAt(i)) != end; i++) { 461 if (ch == '\\') { 462 ch = name.charAt(++i); 463 cb.append((char) ch); 464 } 465 else 466 cb.append((char) ch); 467 } 468 469 if (ch != end) 470 throw new IllegalArgumentException (L.l("`{0}' is an illegal name syntax.", 471 name)); 472 473 String value = cb.toString(); 474 475 properties.put(key, value); 476 } 477 else { 478 cb.clear(); 479 480 for (; i < len && (ch = name.charAt(i)) != ','; i++) 481 cb.append((char) ch); 482 483 properties.put(key, cb.toString()); 484 } 485 } 486 else { 487 throw new IllegalArgumentException (L.l("`{0}' is an illegal name syntax.", 488 name)); 489 } 490 491 for (; i < len && Character.isWhitespace(name.charAt(i)); i++) { 492 } 493 494 if (i < len && name.charAt(i) != ',') 495 throw new IllegalArgumentException (L.l("`{0}' is an illegal name syntax.", 496 name)); 497 498 i++; 499 } 500 } 501 502 505 public static ObjectName getObjectName(String domain, 506 Map <String ,String > properties) 507 throws MalformedObjectNameException 508 { 509 StringBuilder cb = new StringBuilder (); 510 cb.append(domain); 511 cb.append(':'); 512 513 boolean isFirst = true; 514 515 517 String type = properties.get("type"); 518 if (type != null) { 519 cb.append("type="); 520 if (type.matches("[,=:\"*?]")) 521 type = ObjectName.quote(type); 522 cb.append(type); 523 524 isFirst = false; 525 } 526 527 for (String key : properties.keySet()) { 528 if (key.equals("type")) 529 continue; 530 531 if (! isFirst) 532 cb.append(','); 533 isFirst = false; 534 535 cb.append(key); 536 cb.append('='); 537 538 String value = properties.get(key); 539 540 if (value.length() == 0 || value.matches("[,=:\"*?]")) 541 value = ObjectName.quote(value); 542 543 cb.append(value); 544 } 545 546 return new ObjectName(cb.toString()); 547 } 548 549 552 560 561 564 572 573 576 public static Object find(String localName) 577 throws MalformedObjectNameException 578 { 579 return find(getMBeanServer().getContext().getObjectName(localName)); 580 } 581 582 585 public static Object find(ObjectName name) 586 { 587 return find(name, Thread.currentThread().getContextClassLoader()); 588 } 589 590 593 public static Object findGlobal(String localName) 594 throws MalformedObjectNameException 595 { 596 return findGlobal(getMBeanServer().getContext().getObjectName(localName)); 597 } 598 599 602 public static Object findGlobal(ObjectName name) 603 { 604 return find(name, ClassLoader.getSystemClassLoader(), getGlobalMBeanServer()); 605 } 606 607 610 public static Object find(ObjectName name, ClassLoader loader) 611 { 612 return find(name, loader, getMBeanServer()); 613 } 614 615 618 public static Object find(ObjectName name, 619 ClassLoader loader, 620 MBeanServer mbeanServer) 621 { 622 try { 623 ObjectInstance obj = mbeanServer.getObjectInstance(name); 624 625 if (obj == null) 626 return null; 627 628 String className = obj.getClassName(); 629 630 Class cl = Class.forName(className, false, loader); 631 632 Class ifc; 633 634 if (cl.isInterface()) 635 ifc = cl; 636 else 637 ifc = getMBeanInterface(cl); 638 639 if (ifc == null) 640 return null; 641 642 boolean isBroadcast = true; 643 644 Object proxy; 645 646 proxy = JmxInvocationHandler.newProxyInstance(mbeanServer, 647 loader, 648 name, 649 ifc, 650 true); 651 652 return proxy; 653 } catch (InstanceNotFoundException e) { 654 log.log(Level.FINE, e.toString(), e); 655 return null; 656 } catch (ClassNotFoundException e) { 657 log.log(Level.FINE, e.toString(), e); 658 return null; 659 } 660 } 661 662 665 public static ArrayList <Object > query(ObjectName namePattern) 666 { 667 Set <ObjectName> names = getMBeanServer().queryNames(namePattern, null); 668 669 ArrayList <Object > proxy = new ArrayList <Object >(); 670 Iterator <ObjectName> iter = names.iterator(); 671 672 while (iter.hasNext()) { 673 ObjectName name = iter.next(); 674 675 proxy.add(find(name)); 676 } 677 678 return proxy; 679 } 680 681 684 public static void queueAbsolute(TimerTask job, long time) 685 { 686 JobThread.queue(job, time); 687 } 688 689 692 public static void queueRelative(TimerTask job, long delta) 693 { 694 queueAbsolute(job, Alarm.getCurrentTime() + delta); 695 } 696 697 700 public static void dequeue(TimerTask job) 701 { 702 JobThread.dequeue(job); 703 } 704 705 public Jmx() {} 707 708 private static void initStaticMBeans() 709 { 710 try { 711 Class cl = Class.forName("java.lang.Management.ManagementFactory"); 712 713 Method method = cl.getMethod("getPlatformMBeanServer", new Class [0]); 714 715 method.invoke(null, new Object [0]); 716 } catch (Throwable e) { 717 } 718 } 719 } 720 721 | Popular Tags |