1 8 9 package test.javax.management.loading; 10 11 import java.io.File ; 12 import java.io.FileOutputStream ; 13 import java.lang.reflect.Method ; 14 import java.net.URL ; 15 import java.util.List ; 16 import java.util.Random ; 17 import java.util.Set ; 18 import java.util.Iterator ; 19 import javax.management.MBeanRegistration ; 20 import javax.management.MBeanServer ; 21 import javax.management.ObjectInstance ; 22 import javax.management.ObjectName ; 23 import javax.management.ReflectionException ; 24 import javax.management.loading.MLet ; 25 import javax.management.loading.PrivateMLet ; 26 27 import mx4j.MX4JSystemKeys; 28 import mx4j.loading.MLetParseException; 29 import mx4j.loading.MLetParser; 30 import mx4j.loading.MLetTag; 31 import mx4j.server.DefaultClassLoaderRepository; 32 import test.MX4JTestCase; 33 34 37 public class MLetTest extends MX4JTestCase 38 { 39 public MLetTest(String s) 40 { 41 super(s); 42 } 43 44 public void testInvalidMLetFileParsing() throws Exception 45 { 46 MLetParser parser = new MLetParser(); 47 48 String content = null; 49 try 50 { 51 parser.parse(content); 52 fail(); 53 } 54 catch (MLetParseException x) 55 { 56 } 57 58 content = ""; 59 try 60 { 61 parser.parse(content); 62 fail(); 63 } 64 catch (MLetParseException x) 65 { 66 } 67 68 content = " "; 69 try 70 { 71 parser.parse(content); 72 fail(); 73 } 74 catch (MLetParseException x) 75 { 76 } 77 78 content = " <!--"; 79 try 80 { 81 parser.parse(content); 82 fail(); 83 } 84 catch (MLetParseException x) 85 { 86 } 87 88 content = " -->"; 89 try 90 { 91 parser.parse(content); 92 fail(); 93 } 94 catch (MLetParseException x) 95 { 96 } 97 98 content = "<!-- -->\n<!-- ->"; 99 try 100 { 101 parser.parse(content); 102 fail(); 103 } 104 catch (MLetParseException x) 105 { 106 } 107 108 content = "<!- -->"; 109 try 110 { 111 parser.parse(content); 112 fail(); 113 } 114 catch (MLetParseException x) 115 { 116 } 117 118 content = "<!-- -->\n<MLET/>"; 120 try 121 { 122 parser.parse(content); 123 fail(); 124 } 125 catch (MLetParseException x) 126 { 127 } 128 129 content = "<MLET CODE = \" test.mx4j.MBeanNormal\"/>"; 131 try 132 { 133 parser.parse(content); 134 fail(); 135 } 136 catch (MLetParseException x) 137 { 138 } 139 140 content = "\n<MLET CODE=\" test.mx4j.MBeanNormal\">\n</MLET>"; 142 try 143 { 144 parser.parse(content); 145 fail(); 146 } 147 catch (MLetParseException x) 148 { 149 } 150 151 content = "\n<MLET OBJECT=\"mx4j-mbean.ser\">\n</MLET>"; 153 try 154 { 155 parser.parse(content); 156 fail(); 157 } 158 catch (MLetParseException x) 159 { 160 } 161 162 content = "<MLET ARCHIVE = \"..\\lib\"></MLET>"; 164 try 165 { 166 parser.parse(content); 167 fail(); 168 } 169 catch (MLetParseException x) 170 { 171 } 172 173 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" OBJECT=\"mx4j-mbean.ser\" ARCHIVE = \"..\\lib\"></MLET>"; 175 try 176 { 177 parser.parse(content); 178 fail(); 179 } 180 catch (MLetParseException x) 181 { 182 } 183 184 189 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\">\n<ARG></MLET>"; 191 try 192 { 193 parser.parse(content); 194 fail(); 195 } 196 catch (MLetParseException x) 197 { 198 } 199 200 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\">\n<ARG type=\"int\"></MLET>"; 202 try 203 { 204 parser.parse(content); 205 fail(); 206 } 207 catch (MLetParseException x) 208 { 209 } 210 211 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\">\n<ARG value=\"int\"></MLET>"; 213 try 214 { 215 parser.parse(content); 216 fail(); 217 } 218 catch (MLetParseException x) 219 { 220 } 221 222 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\" name>\n</MLET>"; 224 try 225 { 226 parser.parse(content); 227 fail(); 228 } 229 catch (MLetParseException x) 230 { 231 } 232 233 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\" name=>\n</MLET>"; 235 try 236 { 237 parser.parse(content); 238 fail(); 239 } 240 catch (MLetParseException x) 241 { 242 } 243 244 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\" version>\n</MLET>"; 246 try 247 { 248 parser.parse(content); 249 fail(); 250 } 251 catch (MLetParseException x) 252 { 253 } 254 255 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE = \"..\\lib\" version=>\n</MLET>"; 257 try 258 { 259 parser.parse(content); 260 fail(); 261 } 262 catch (MLetParseException x) 263 { 264 } 265 266 } 267 268 public void testValidMLetFileParsing() throws Exception 269 { 270 MLetParser parser = new MLetParser(); 271 String content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE=\"mx4j-tests.jar\" NAME=\":name=MLetTest1\"/>"; 272 parser.parse(content); 273 274 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE=\"mx4j-tests.jar\" NAME=\":name=MLetTest2\">\n\t<ARG TYPE=\"int\" VALUE=\"5\">\n</MLET>\n"; 275 parser.parse(content); 276 277 content = "<MLET CODE=\"test.mx4j.MBeanNormal\" ARCHIVE=\"mx4j-tests.jar\" CODEBASE=\"dist\\test\\\" NAME=\":name=MLetTest3\">\n\t<ARG TYPE=\"int\" VALUE=\"5\"/>\n</MLET>\n"; 278 parser.parse(content); 279 } 280 281 public void testCompleteMLetFileParsing() throws Exception 282 { 283 MLetParser parser = new MLetParser(); 284 285 StringBuffer content = new StringBuffer (); 286 content.append("<!-- Comment -->"); 287 content.append("<MLET \n"); 288 content.append(" Code=\"mx4j.tools.naming.NamingService\"\n"); 289 content.append(" archive = \" ../lib \"\n"); 290 content.append(" CodeBase= \"http://localhost:8080/download\"\n"); 291 content.append(" NAME=\":name=test\"\n"); 292 content.append(" Version=\"1\">\n"); 293 content.append(" <!-- Comment -->"); 294 content.append(" <ARG \n"); 295 content.append(" Type=\"boolean\"\n"); 296 content.append(" VALUE = \"true\">\n"); 297 content.append(" <!-- Comment -->"); 298 content.append(" <ARG \n"); 299 content.append(" TYPE = \"boolean\"\n"); 300 content.append(" value=\"true\"/>\n"); 301 content.append("</MLet>"); 302 303 parser.parse(content.toString()); 304 } 305 306 public void testCodebaseForGetMBeansFromURL() throws Exception 307 { 308 Class cls = Simple.class; 309 String className = cls.getName(); 310 URL url = cls.getProtectionDomain().getCodeSource().getLocation(); 311 String urlString = url.toExternalForm(); 312 int index = urlString.lastIndexOf('/') + 1; 313 String jar = urlString.substring(index); 314 315 String codebase = "."; 316 String content = "<MLET CODE=\"" + className + "\" NAME=\":name=test\" ARCHIVE=\"" + jar + "\" CODEBASE=\"" + codebase + "\"/>"; 317 MLetParser parser = new MLetParser(); 318 List tags = parser.parse(content); 319 MLetTag tag = (MLetTag)tags.get(0); 320 URL mletFileURL = new URL ("http://mx4j.sourceforge.net/mlets/mbeans.mlet"); 321 URL codebaseURL = tag.normalizeCodeBase(mletFileURL); 322 assertEquals(codebaseURL.toExternalForm(), "http://mx4j.sourceforge.net/mlets/"); 323 324 content = "<MLET CODE=\"" + className + "\" NAME=\":name=test\" ARCHIVE=\"" + jar + "\"/>"; 325 tags = parser.parse(content); 326 tag = (MLetTag)tags.get(0); 327 codebaseURL = tag.normalizeCodeBase(mletFileURL); 328 assertEquals(codebaseURL.toExternalForm(), "http://mx4j.sourceforge.net/mlets/"); 329 330 codebase = "../lib"; 331 content = "<MLET CODE=\"" + className + "\" NAME=\":name=test\" ARCHIVE=\"" + jar + "\" CODEBASE=\"" + codebase + "\"/>"; 332 tags = parser.parse(content); 333 tag = (MLetTag)tags.get(0); 334 codebaseURL = tag.normalizeCodeBase(mletFileURL); 335 assertEquals(codebaseURL.toExternalForm(), "http://mx4j.sourceforge.net/lib/"); 336 337 codebase = "ftp://mx4j.sourceforge.net/mbeans"; 338 content = "<MLET CODE=\"" + className + "\" NAME=\":name=test\" ARCHIVE=\"" + jar + "\" CODEBASE=\"" + codebase + "\"/>"; 339 tags = parser.parse(content); 340 tag = (MLetTag)tags.get(0); 341 codebaseURL = tag.normalizeCodeBase(mletFileURL); 342 assertEquals(codebaseURL.toExternalForm(), codebase + "/"); 343 } 344 345 public void testGetMBeansFromURL() throws Exception 346 { 347 Class cls = Simple.class; 348 String className = cls.getName(); 349 URL url = cls.getProtectionDomain().getCodeSource().getLocation(); 350 String urlString = url.toExternalForm(); 351 int index = urlString.lastIndexOf('/') + 1; 352 String jar = urlString.substring(index); 353 String codebase = urlString.substring(0, index); 354 355 File mletFile = File.createTempFile("mlet", null); 357 mletFile.deleteOnExit(); 358 FileOutputStream fos = new FileOutputStream (mletFile); 359 String content = "<MLET CODE=\"" + className + "\" NAME=\":name=test\" ARCHIVE=\"" + jar + "\" CODEBASE=\"" + codebase + "\"/>"; 360 fos.write(content.getBytes()); 361 fos.close(); 362 363 System.setProperty(MX4JSystemKeys.MX4J_MBEANSERVER_CLASSLOADER_REPOSITORY, CLRWithOnlyMLets.class.getName()); 364 MBeanServer server = newMBeanServer(); 365 366 ObjectName mletName = new ObjectName (":loader=mlet1"); 367 368 MLet mlet = new MLet (); 369 server.registerMBean(mlet, mletName); 370 371 Set mbeans = mlet.getMBeansFromURL(mletFile.toURL()); 372 if (mbeans.size() != 1) fail("Loaded wrong number of MBeans"); 373 ObjectInstance instance = (ObjectInstance )mbeans.iterator().next(); 374 if (!instance.getClassName().equals(className)) fail("Loaded a different MBean"); 375 } 376 377 public void testGetMBeansFromURLWithNoName() throws Exception 378 { 379 Class cls = SimpleRegistration.class; 380 String className = cls.getName(); 381 URL url = cls.getProtectionDomain().getCodeSource().getLocation(); 382 String urlString = url.toExternalForm(); 383 int index = urlString.lastIndexOf('/') + 1; 384 String jar = urlString.substring(index); 385 String codebase = urlString.substring(0, index); 386 387 File mletFile = File.createTempFile("mletnoname", null); 389 mletFile.deleteOnExit(); 390 FileOutputStream fos = new FileOutputStream (mletFile); 391 String content = "<MLET CODE=\"" + className + "\" ARCHIVE=\"" + jar + "\" CODEBASE=\"" + codebase + "\"/>"; 392 fos.write(content.getBytes()); 393 fos.close(); 394 395 System.setProperty(MX4JSystemKeys.MX4J_MBEANSERVER_CLASSLOADER_REPOSITORY, CLRWithOnlyMLets.class.getName()); 396 MBeanServer server = newMBeanServer(); 397 398 ObjectName mletName = new ObjectName (":loader=mlet1"); 399 MLet mlet = new MLet (); 400 server.registerMBean(mlet, mletName); 401 402 Set mbeans = mlet.getMBeansFromURL(mletFile.toURL()); 403 if (mbeans.size() != 1) fail("Loaded wrong number of MBeans"); 404 ObjectInstance instance = (ObjectInstance )mbeans.iterator().next(); 405 if (!instance.getClassName().equals(className)) fail("Loaded a different MBean"); 406 } 407 408 public void testMLetDelegatesToCLR() throws Exception 409 { 410 mletDelegationToCLR(true); 411 } 412 413 public void testMLetDoesNotDelegateToCLR() throws Exception 414 { 415 try 416 { 417 mletDelegationToCLR(false); 418 fail("MLet does not delegate, cannot load the class"); 419 } 420 catch (ReflectionException ignored) 421 { 422 } 423 } 424 425 public void mletDelegationToCLR(boolean delegates) throws Exception 426 { 427 System.setProperty(MX4JSystemKeys.MX4J_MBEANSERVER_CLASSLOADER_REPOSITORY, CLRWithOnlyMLets.class.getName()); 428 MBeanServer server = newMBeanServer(); 429 430 ObjectName loaderName = new ObjectName ("Loader", "id", "0"); 431 ObjectName mletName = new ObjectName ("Loader", "id", "1"); 432 ObjectName mbeanName = new ObjectName ("MBean", "id", "0"); 433 434 Class cls = Simple.class; 435 URL url = cls.getProtectionDomain().getCodeSource().getLocation(); 436 String className = cls.getName(); 437 438 MLet loader = new MLet (new URL []{url}, ClassLoader.getSystemClassLoader().getParent()); 439 server.registerMBean(loader, loaderName); 440 441 MLet mlet = new MLet (new URL [0], ClassLoader.getSystemClassLoader().getParent(), delegates); 442 443 try 445 { 446 mlet.loadClass(className); 447 fail("MLet should not be able to load the class"); 448 } 449 catch (ClassNotFoundException ignored) 450 { 451 } 452 453 server.registerMBean(mlet, mletName); 454 455 server.createMBean(className, mbeanName, mletName); 457 } 458 459 public void testSingleMLetLoadClass() throws Exception 460 { 461 System.setProperty(MX4JSystemKeys.MX4J_MBEANSERVER_CLASSLOADER_REPOSITORY, CLRWithOnlyMLets.class.getName()); 462 MBeanServer server = newMBeanServer(); 463 464 ObjectName loaderName = new ObjectName ("Loader", "id", "0"); 465 ObjectName mbeanName = new ObjectName ("MBean", "id", "0"); 466 467 Class cls = Simple.class; 468 URL url = cls.getProtectionDomain().getCodeSource().getLocation(); 469 String className = cls.getName(); 470 471 MLet mlet = new MLet (new URL []{url}, ClassLoader.getSystemClassLoader().getParent()); 472 server.registerMBean(mlet, loaderName); 473 474 server.createMBean(className, mbeanName, loaderName); 475 } 476 477 public void testManyMLetLoadClass() throws Exception 478 { 479 int loaderCount = 100; 480 int mbeanCount = 200; 481 482 long elapsed = manyMLetLoadClass(loaderCount, mbeanCount, Simple.class.getName(), false); 483 484 System.out.println("Loading " + mbeanCount + " MBeans with " + loaderCount + " MLets took " + elapsed + " ms, average is " + (elapsed / mbeanCount)); 485 if (elapsed > mbeanCount * 500) fail("Test took too much time, probably a problem in MLet loading"); 487 } 488 489 public void testMultiMLetLoadNonExistingClass() throws Exception 490 { 491 int loaderCount = 100; 492 int mbeanCount = 200; 493 494 long elapsed = manyMLetLoadClass(loaderCount, mbeanCount, "dummy", true); 495 496 System.out.println("Loading " + mbeanCount + " non-existing MBeans with " + loaderCount + " MLets took " + elapsed + " ms, average is " + (elapsed / mbeanCount)); 497 if (elapsed > mbeanCount * loaderCount * 5) fail("Test took too much time, probably a problem in MLet loading"); 503 } 504 505 private long manyMLetLoadClass(int loaderCount, int mbeanCount, String className, boolean ignoreExceptionOnCreation) throws Exception 506 { 507 ObjectName [] loaders = new ObjectName [loaderCount]; 508 ObjectName [] mbeans = new ObjectName [mbeanCount]; 509 510 MBeanServer server = newMBeanServer(); 511 512 URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); 513 514 for (int i = 0; i < loaderCount; ++i) 516 { 517 loaders[i] = new ObjectName ("Loader", "id", String.valueOf(i)); 518 MLet mlet = new MLet (new URL []{url}, ClassLoader.getSystemClassLoader().getParent()); 519 server.registerMBean(mlet, loaders[i]); 520 } 521 522 long start = System.currentTimeMillis(); 523 524 Random random = new Random (start); 525 for (int i = 0; i < mbeanCount; ++i) 526 { 527 mbeans[i] = new ObjectName ("MBean", "id", String.valueOf(i)); 528 529 int id = random.nextInt(loaderCount); 531 ObjectName loader = loaders[id]; 532 533 if (ignoreExceptionOnCreation) 534 { 535 try 536 { 537 server.createMBean(className, mbeans[i], loader); 538 } 539 catch (ReflectionException ignored) 540 { 541 } 542 } 543 else 544 { 545 server.createMBean(className, mbeans[i], loader); 546 } 547 } 548 549 long end = System.currentTimeMillis(); 550 551 return end - start; 552 } 553 554 public void testChildMLetRegisteredBeforeParentMLet() throws Exception 555 { 556 558 URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); 559 MLet parent = new MLet (new URL []{url}, ClassLoader.getSystemClassLoader().getParent()); 560 MLet child = new MLet (new URL [0], parent); 561 562 ObjectName parentName = new ObjectName ("MLet", "type", "parent"); 563 ObjectName childName = new ObjectName ("MLet", "type", "child"); 564 565 MBeanServer server = newMBeanServer(); 566 567 server.registerMBean(child, childName); 569 server.registerMBean(parent, parentName); 570 571 try 576 { 577 parent.loadClass("dummy"); 578 fail("Class does not exist"); 579 } 580 catch (ClassNotFoundException ignored) 581 { 582 } 583 } 584 585 public void testPrivateMLetNotAddedToCLR() throws Exception 586 { 587 Class cls = Simple.class; 588 URL url = cls.getProtectionDomain().getCodeSource().getLocation(); 589 PrivateMLet mlet = new PrivateMLet (new URL []{url}, ClassLoader.getSystemClassLoader().getParent(), true); 590 591 ObjectName mletName = new ObjectName (":MLet=Private"); 592 ObjectName mbeanName = new ObjectName (":MBean=Simple"); 593 594 System.setProperty(MX4JSystemKeys.MX4J_MBEANSERVER_CLASSLOADER_REPOSITORY, CLRWithOnlyMLets.class.getName()); 595 MBeanServer server = newMBeanServer(); 596 597 server.registerMBean(mlet, mletName); 599 600 try 601 { 602 server.createMBean(cls.getName(), mbeanName); 604 fail("Class cannot be found by the CLR"); 605 } 606 catch (ReflectionException ignored) 607 { 608 } 609 } 610 611 public void testFindLibrary() throws Exception 612 { 613 MLet mlet = new MLet (); 614 Method method = mlet.getClass().getDeclaredMethod("findLibrary", new Class []{String .class}); 615 method.setAccessible(true); 616 String result = (String )method.invoke(mlet, new Object []{"stat"}); 617 if (result != null) fail("MLet can load non-existing libraries"); 618 } 619 620 public void testFindLibraryWithLibraryDirectoryInClassPath() throws Exception 621 { 622 String library = "mlet"; 624 String libraryName = System.mapLibraryName(library); 625 File libraryFile = new File (libraryName); 626 FileOutputStream fos = new FileOutputStream (libraryFile); 627 fos.write("library".getBytes()); 628 fos.close(); 629 630 assertTrue(libraryFile.exists()); 631 assertTrue(libraryFile.length() > 0); 632 633 MLet mlet = new MLet (new URL []{libraryFile.getCanonicalFile().getParentFile().toURL()}); 634 Method method = mlet.getClass().getDeclaredMethod("findLibrary", new Class []{String .class}); 635 method.setAccessible(true); 636 String result = (String )method.invoke(mlet, new Object []{library}); 637 638 assertNotNull(result); 639 assertTrue(libraryFile.exists()); 640 assertTrue(libraryFile.length() > 0); 641 } 642 643 public void testFindLibraryWithLibraryDirectoryNotInClassPath() throws Exception 644 { 645 String library = "mlet"; 647 String libraryName = System.mapLibraryName(library); 648 File libraryFile = new File (libraryName); 649 FileOutputStream fos = new FileOutputStream (libraryFile); 650 fos.write("library".getBytes()); 651 fos.close(); 652 653 assertTrue(libraryFile.exists()); 654 assertTrue(libraryFile.length() > 0); 655 656 MLet mlet = new MLet (new URL []{libraryFile.getCanonicalFile().getParentFile().toURL()}); 657 658 File temp = File.createTempFile("abc", null); 660 temp.deleteOnExit(); 661 mlet.setLibraryDirectory(temp.getCanonicalFile().getParentFile().getCanonicalPath()); 662 663 Method method = mlet.getClass().getDeclaredMethod("findLibrary", new Class []{String .class}); 664 method.setAccessible(true); 665 String result = (String )method.invoke(mlet, new Object []{library}); 666 667 assertNotNull(result); 668 assertTrue(libraryFile.exists()); 669 assertTrue(libraryFile.length() > 0); 670 671 File tempLibrary = new File (mlet.getLibraryDirectory(), libraryName); 672 assertTrue(tempLibrary.exists()); 673 assertTrue(tempLibrary.length() > 0); 674 } 675 676 public void testDefaultMletName() throws Exception { 677 MBeanServer mbServer = newMBeanServer(); 678 MLet mlet = new MLet (); 679 ObjectName mletName = new ObjectName (mbServer.getDefaultDomain(), "type", "MLet"); 680 assertFalse(mbServer.isRegistered(mletName)); 681 assertEquals(mletName, mbServer.registerMBean(mlet, null).getObjectName()); 682 assertTrue(mbServer.isRegistered(mletName)); 683 } 684 685 public interface SimpleMBean 686 { 687 } 688 689 public static class Simple implements SimpleMBean 690 { 691 } 692 693 public static class SimpleRegistration extends Simple implements MBeanRegistration 694 { 695 public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception 696 { 697 return ObjectName.getInstance(":name=simple"); 698 } 699 700 public void postRegister(Boolean registrationDone) 701 { 702 } 703 704 public void preDeregister() throws Exception 705 { 706 } 707 708 public void postDeregister() 709 { 710 } 711 } 712 713 public static class CLRWithOnlyMLets extends DefaultClassLoaderRepository 714 { 715 protected void addClassLoader(ClassLoader cl) 716 { 717 if (cl == null) return; 718 if (cl.getClass() == MLet .class || cl.getClass() == PrivateMLet .class) super.addClassLoader(cl); 719 } 720 } 721 } 722 | Popular Tags |