1 19 20 package org.netbeans.core.startup; 21 22 import java.io.ByteArrayInputStream ; 23 import java.io.File ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.lang.ref.WeakReference ; 28 import java.lang.reflect.Field ; 29 import java.lang.reflect.Method ; 30 import java.net.JarURLConnection ; 31 import java.net.URL ; 32 import java.net.URLClassLoader ; 33 import java.net.URLConnection ; 34 import java.util.ArrayList ; 35 import java.util.Arrays ; 36 import java.util.Collection ; 37 import java.util.Collections ; 38 import java.util.Enumeration ; 39 import java.util.HashMap ; 40 import java.util.HashSet ; 41 import java.util.Iterator ; 42 import java.util.LinkedHashSet ; 43 import java.util.List ; 44 import java.util.Locale ; 45 import java.util.Map ; 46 import java.util.Random ; 47 import java.util.Set ; 48 import java.util.jar.JarEntry ; 49 import java.util.jar.JarFile ; 50 import java.util.jar.JarOutputStream ; 51 import java.util.jar.Manifest ; 52 import java.util.logging.Level ; 53 import org.netbeans.InvalidException; 54 import org.netbeans.Module; 55 import org.netbeans.ModuleManager; 56 import org.netbeans.Util; 57 import org.netbeans.core.startup.SetupHid.FakeEvents; 58 import org.netbeans.core.startup.SetupHid.FakeModuleInstaller; 59 import org.netbeans.core.startup.SetupHid.LoggedPCListener; 60 import org.openide.filesystems.FileUtil; 61 import org.openide.modules.Dependency; 62 import org.openide.modules.ModuleInfo; 63 import org.openide.util.Lookup; 64 import org.openide.util.LookupEvent; 65 import org.openide.util.LookupListener; 66 import org.openide.util.Utilities; 67 68 84 public class ModuleManagerTest extends SetupHid { 85 86 static { 87 new URLConnection (ModuleManagerTest.class.getResource("ModuleManagerTest.class")) { 89 public void connect() throws IOException {} 90 }.setDefaultUseCaches(false); 91 } 92 93 public ModuleManagerTest(String name) { 94 super(name); 95 } 96 97 102 103 @Override 104 protected Level logLevel() { 105 return Level.FINE; 106 } 107 108 113 public void testSimpleInstallation() throws Exception { 114 FakeModuleInstaller installer = new FakeModuleInstaller(); 115 FakeEvents ev = new FakeEvents(); 116 ModuleManager mgr = new ModuleManager(installer, ev); 117 mgr.mutexPrivileged().enterWriteAccess(); 118 try { 119 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 120 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 121 assertEquals("org.foo", m1.getCodeNameBase()); 122 assertEquals("org.bar", m2.getCodeNameBase()); 123 assertEquals(Collections.EMPTY_SET, m1.getDependencies()); 124 assertEquals(Dependency.create(Dependency.TYPE_MODULE, "org.foo/1"), m2.getDependencies()); 125 Map <String ,Module> modulesByName = new HashMap <String ,Module>(); 126 modulesByName.put(m1.getCodeNameBase(), m1); 127 modulesByName.put(m2.getCodeNameBase(), m2); 128 List <Module> m1m2 = Arrays.asList(m1, m2); 129 List <Module> m2m1 = Arrays.asList(m2, m1); 130 Map <Module,List <Module>> deps = Util.moduleDependencies(m1m2, modulesByName, Collections.<String ,Set <Module>>emptyMap()); 131 assertNull(deps.get(m1)); 132 assertEquals(Collections.singletonList(m1), deps.get(m2)); 133 assertEquals(m2m1, Utilities.topologicalSort(m1m2, deps)); 134 assertEquals(m2m1, Utilities.topologicalSort(m2m1, deps)); 135 141 Set <Module> m1PlusM2 = new HashSet <Module>(); 142 m1PlusM2.add(m1); 143 m1PlusM2.add(m2); 144 List <Module> toEnable = mgr.simulateEnable(m1PlusM2); 145 assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable); 146 mgr.enable(m1PlusM2); 147 assertEquals(Arrays.asList( 148 "prepare", 149 "prepare", 150 "load" 151 ), installer.actions); 152 assertEquals(Arrays.asList( 153 m1, 154 m2, 155 Arrays.asList(m1, m2) 156 ), installer.args); 157 Class somethingelse = Class.forName("org.bar.SomethingElse", true, m2.getClassLoader()); 158 Method somemethod = somethingelse.getMethod("message"); 159 assertEquals("hello", somemethod.invoke(somethingelse.newInstance())); 160 installer.clear(); 161 List <Module> toDisable = mgr.simulateDisable(Collections.singleton(m1)); 162 assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), toDisable); 163 toDisable = mgr.simulateDisable(m1PlusM2); 164 assertEquals("correct result of simulateDisable #2", Arrays.asList(m2, m1), toDisable); 165 mgr.disable(m1PlusM2); 166 assertFalse(m1.isEnabled()); 167 assertFalse(m2.isEnabled()); 168 assertEquals(Collections.EMPTY_SET, mgr.getEnabledModules()); 169 assertEquals(m1PlusM2, mgr.getModules()); 170 assertEquals(Arrays.asList( 171 "unload", 172 "dispose", 173 "dispose" 174 ), installer.actions); 175 assertEquals(Arrays.asList( 176 Arrays.asList(m2, m1), 177 m2, 178 m1 179 ), installer.args); 180 installer.clear(); 181 mgr.enable(m1); 182 mgr.shutDown(); 183 assertEquals(Arrays.asList( 184 "prepare", 185 "load", 186 "closing", 187 "close" 188 ), installer.actions); 189 assertEquals(Arrays.asList( 190 m1, 191 Collections.singletonList(m1), 192 Collections.singletonList(m1), 193 Collections.singletonList(m1) 194 ), installer.args); 195 } finally { 196 mgr.mutexPrivileged().exitWriteAccess(); 197 } 198 } 199 200 public void testInstallAutoload() throws Exception { 201 FakeModuleInstaller installer = new FakeModuleInstaller(); 203 FakeEvents ev = new FakeEvents(); 204 ModuleManager mgr = new ModuleManager(installer, ev); 205 mgr.mutexPrivileged().enterWriteAccess(); 206 try { 207 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 208 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, true, false); 210 try { 211 mgr.simulateEnable(new HashSet <Module>(Arrays.asList(m1, m2))); 212 assertTrue("Should not permit you to simulate enablement of an autoload", false); 213 } catch (IllegalArgumentException iae) { 214 } 216 assertEquals(Collections.EMPTY_SET, m1.getProblems()); 217 assertEquals(Collections.EMPTY_SET, m2.getProblems()); 218 List toEnable = mgr.simulateEnable(Collections.singleton(m2)); 219 assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable); 220 mgr.enable(Collections.singleton(m2)); 221 assertEquals(Arrays.asList( 222 "prepare", 223 "prepare", 224 "load" 225 ), installer.actions); 226 assertEquals(Arrays.asList( 227 m1, 228 m2, 229 Arrays.asList(m1, m2) 230 ), installer.args); 231 Class somethingelse = Class.forName("org.bar.SomethingElse", true, m2.getClassLoader()); 232 Method somemethod = somethingelse.getMethod("message"); 233 assertEquals("hello", somemethod.invoke(somethingelse.newInstance())); 234 assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), mgr.simulateDisable(Collections.singleton(m2))); 236 installer.clear(); 237 mgr.disable(Collections.singleton(m2)); 238 assertEquals(Arrays.asList( 239 "unload", 240 "dispose", 241 "dispose" 242 ), installer.actions); 243 assertEquals(Arrays.asList( 244 Arrays.asList(m2, m1), 245 m2, 246 m1 247 ), installer.args); 248 } finally { 249 mgr.mutexPrivileged().exitWriteAccess(); 250 } 251 } 252 253 public void testInstallEager() throws Exception { 254 FakeModuleInstaller installer = new FakeModuleInstaller(); 256 FakeEvents ev = new FakeEvents(); 257 ModuleManager mgr = new ModuleManager(installer, ev); 258 mgr.mutexPrivileged().enterWriteAccess(); 259 try { 260 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 261 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, true); 263 try { 264 mgr.simulateEnable(new HashSet <Module>(Arrays.asList(m1, m2))); 265 fail("Should not permit you to simulate enablement of an eager module"); 266 } catch (IllegalArgumentException iae) { 267 } 269 assertEquals(Collections.EMPTY_SET, m1.getProblems()); 270 assertEquals(Collections.EMPTY_SET, m2.getProblems()); 271 List toEnable = mgr.simulateEnable(Collections.singleton(m1)); 272 assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable); 273 mgr.enable(Collections.singleton(m1)); 274 assertEquals(Arrays.asList( 275 "prepare", 276 "prepare", 277 "load" 278 ), installer.actions); 279 assertEquals(Arrays.asList( 280 m1, 281 m2, 282 Arrays.asList(m1, m2) 283 ), installer.args); 284 Class somethingelse = Class.forName("org.bar.SomethingElse", true, m2.getClassLoader()); 285 Method somemethod = somethingelse.getMethod("message"); 286 assertEquals("hello", somemethod.invoke(somethingelse.newInstance())); 287 assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), mgr.simulateDisable(Collections.singleton(m1))); 289 installer.clear(); 290 mgr.disable(Collections.singleton(m1)); 291 assertEquals(Arrays.asList( 292 "unload", 293 "dispose", 294 "dispose" 295 ), installer.actions); 296 assertEquals(Arrays.asList( 297 Arrays.asList(m2, m1), 298 m2, 299 m1 300 ), installer.args); 301 } finally { 302 mgr.mutexPrivileged().exitWriteAccess(); 303 } 304 } 305 306 public void testEagerPlusAutoload() throws Exception { 307 FakeModuleInstaller installer = new FakeModuleInstaller(); 308 FakeEvents ev = new FakeEvents(); 309 ModuleManager mgr = new ModuleManager(installer, ev); 310 mgr.mutexPrivileged().enterWriteAccess(); 311 try { 312 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, true, false); 314 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 315 Module m3 = mgr.create(new File (jars, "dep-on-dep-on-simple.jar"), null, false, false, true); 316 List toEnable = mgr.simulateEnable(Collections.singleton(m2)); 317 assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2, m3), toEnable); 318 mgr.enable(Collections.singleton(m2)); 319 assertEquals(Arrays.asList( 320 "prepare", 321 "prepare", 322 "prepare", 323 "load" 324 ), installer.actions); 325 assertEquals(Arrays.asList( 326 m1, 327 m2, 328 m3, 329 Arrays.asList(m1, m2, m3) 330 ), installer.args); 331 Class somethingelseagain = Class.forName("org.baz.SomethingElseAgain", true, m3.getClassLoader()); 332 Method somemethod = somethingelseagain.getMethod("doit"); 333 assertEquals("hello", somemethod.invoke(somethingelseagain.newInstance())); 334 assertEquals("correct result of simulateDisable", Arrays.asList(m3, m2, m1), mgr.simulateDisable(Collections.singleton(m2))); 335 installer.clear(); 336 mgr.disable(Collections.singleton(m2)); 337 assertEquals(Arrays.asList( 338 "unload", 339 "dispose", 340 "dispose", 341 "dispose" 342 ), installer.actions); 343 assertEquals(Arrays.asList( 344 Arrays.asList(m3, m2, m1), 345 m3, 346 m2, 347 m1 348 ), installer.args); 349 } finally { 350 mgr.mutexPrivileged().exitWriteAccess(); 351 } 352 } 353 354 358 public void testEagerPlusAutoload2() throws Exception { 359 FakeModuleInstaller installer = new FakeModuleInstaller(); 360 FakeEvents ev = new FakeEvents(); 361 ModuleManager mgr = new ModuleManager(installer, ev); 362 mgr.mutexPrivileged().enterWriteAccess(); 363 try { 364 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, true, false); 366 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 367 Module m3 = mgr.create(new File (jars, "depends-on-simple-module-2.jar"), null, false, false, true); 368 assertTrue(m1.isEnabled()); 369 assertFalse(m2.isEnabled()); 370 assertTrue(m3.isEnabled()); 371 List toEnable = mgr.simulateEnable(Collections.singleton(m2)); 372 assertEquals("correct result of simulateEnable", Collections.singletonList(m2), toEnable); 373 mgr.enable(Collections.singleton(m2)); 374 assertTrue(m1.isEnabled()); 375 assertTrue(m2.isEnabled()); 376 assertTrue(m3.isEnabled()); 377 List toDisable = mgr.simulateDisable(Collections.singleton(m2)); 378 assertEquals("correct result of simulateDisable", Collections.singletonList(m2), toDisable); 379 mgr.disable(Collections.singleton(m2)); 380 assertTrue(m1.isEnabled()); 381 assertFalse(m2.isEnabled()); 382 assertTrue(m3.isEnabled()); 383 } finally { 384 mgr.mutexPrivileged().exitWriteAccess(); 385 } 386 } 387 388 public void testEagerEnabledImmediately() throws Exception { 389 FakeModuleInstaller installer = new FakeModuleInstaller(); 390 FakeEvents ev = new FakeEvents(); 391 ModuleManager mgr = new ModuleManager(installer, ev); 392 mgr.mutexPrivileged().enterWriteAccess(); 393 try { 394 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, true); 395 assertTrue(m1.isEnabled()); 396 } finally { 397 mgr.mutexPrivileged().exitWriteAccess(); 398 } 399 mgr = new ModuleManager(installer, ev); 400 mgr.mutexPrivileged().enterWriteAccess(); 401 try { 402 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 403 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, true); 404 assertFalse(m1.isEnabled()); 405 assertFalse(m2.isEnabled()); 406 mgr.enable(m1); 407 assertTrue(m1.isEnabled()); 408 assertTrue(m2.isEnabled()); 409 } finally { 410 mgr.mutexPrivileged().exitWriteAccess(); 411 } 412 mgr = new ModuleManager(installer, ev); 413 mgr.mutexPrivileged().enterWriteAccess(); 414 try { 415 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, true, false); 416 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, true); 417 assertTrue(m1.isEnabled()); 418 assertTrue(m2.isEnabled()); 419 } finally { 420 mgr.mutexPrivileged().exitWriteAccess(); 421 } 422 } 423 424 public void testCyclic() throws Exception { 425 FakeModuleInstaller installer = new FakeModuleInstaller(); 427 FakeEvents ev = new FakeEvents(); 428 ModuleManager mgr = new ModuleManager(installer, ev); 429 mgr.mutexPrivileged().enterWriteAccess(); 430 try { 431 Module cyc1 = mgr.create(new File (jars, "cyclic-1.jar"), null, false, false, false); 432 Module cyc2 = mgr.create(new File (jars, "cyclic-2.jar"), null, false, false, false); 433 Module cycd = mgr.create(new File (jars, "depends-on-cyclic-1.jar"), null, false, false, false); 434 Set <Module> circular = new HashSet <Module>(Arrays.asList(cyc1, cyc2, cycd)); 435 assertEquals("correct result of simulateEnable", Collections.EMPTY_LIST, mgr.simulateEnable(circular)); 436 assertEquals("cyc1 problems include cyc2", cyc1.getDependencies(), cyc1.getProblems()); 437 assertEquals("cyc2 problems include cyc1", cyc2.getDependencies(), cyc2.getProblems()); 438 assertEquals("cycd problems include cyc1", cycd.getDependencies(), cycd.getProblems()); 439 } finally { 440 mgr.mutexPrivileged().exitWriteAccess(); 441 } 442 } 443 444 public void testBuildVersionCanBeReadOrIsDelegated() throws Exception { 445 FakeModuleInstaller installer = new FakeModuleInstaller(); 447 FakeEvents ev = new FakeEvents(); 448 ModuleManager mgr = new ModuleManager(installer, ev); 449 mgr.mutexPrivileged().enterWriteAccess(); 450 try { 451 Module cyc1 = mgr.create(new File (jars, "cyclic-1.jar"), null, false, false, false); 452 Module cyc2 = mgr.create(new File (jars, "cyclic-2.jar"), null, false, false, false); 453 454 String impl1 = cyc1.getImplementationVersion (); 455 String impl2 = cyc2.getImplementationVersion (); 456 String bld1 = cyc1.getBuildVersion (); 457 String bld2 = cyc2.getBuildVersion (); 458 459 assertEquals ( 460 "cyc1 does not define build version and thus it is same as impl", 461 impl1, bld1 462 ); 463 464 assertEquals ( 465 "cyc2 does define build version", 466 "this_line_is_here_due_to_yarda", 467 bld2 468 ); 469 470 assertTrue ("Impl and build versions are not same", 471 !bld2.equals (impl2) 472 ); 473 } finally { 474 mgr.mutexPrivileged().exitWriteAccess(); 475 } 476 } 477 478 public void testLookup() throws Exception { 479 FakeModuleInstaller installer = new FakeModuleInstaller(); 480 FakeEvents ev = new FakeEvents(); 481 ModuleManager mgr = new ModuleManager(installer, ev); 482 mgr.mutexPrivileged().enterWriteAccess(); 483 Module m1, m2; 484 try { 485 m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 486 m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 487 } finally { 488 mgr.mutexPrivileged().exitWriteAccess(); 489 } 490 Lookup l = mgr.getModuleLookup(); 491 assertNull(l.lookup(String .class)); 492 Object random = l.lookup(ModuleInfo.class); 493 assertTrue(random == m1 || random == m2); 494 random = l.lookup(Module.class); 495 assertTrue(random == m1 || random == m2); 496 Lookup.Result<ModuleInfo> resultAll = l.lookupResult(ModuleInfo.class); 497 assertEquals("finding all instances works", new HashSet <Module>(Arrays.asList(m1, m2)), new HashSet <ModuleInfo>(resultAll.allInstances())); 498 Lookup.Result<Module> resultInstance2 = l.lookup(new Lookup.Template<Module>(null, null, m2)); 499 assertEquals("finding one specific instance works", Collections.singleton(m2), new HashSet <Module>(resultInstance2.allInstances())); 500 Collection <? extends Lookup.Item<Module>> items = resultInstance2.allItems(); 501 assertTrue(items.size() == 1); 502 Lookup.Item<Module> item = items.iterator().next(); 503 assertEquals(m2, item.getInstance()); 504 Util.err.info("Item ID: " + item.getId()); 505 assertTrue("Item class is OK: " + item.getType(), item.getType().isAssignableFrom(Module.class)); 506 assertEquals("finding by ID works", Collections.singleton(m2), new HashSet <Module>(l.lookup(new Lookup.Template<Module>(null, item.getId(), null)).allInstances())); 507 final boolean[] waiter = new boolean[] {false}; 508 resultAll.addLookupListener(new LookupListener() { 509 public void resultChanged(LookupEvent lev) { 510 Util.err.info("Got event: " + lev); 511 synchronized (waiter) { 512 waiter[0] = true; 513 waiter.notify(); 514 } 515 } 516 }); 517 Module m3; 518 mgr.mutexPrivileged().enterWriteAccess(); 519 try { 520 m3 = mgr.create(new File (jars, "cyclic-1.jar"), null, false, false, false); 521 mgr.delete(m2); 522 } finally { 523 mgr.mutexPrivileged().exitWriteAccess(); 524 } 525 assertEquals("results changed", new HashSet <ModuleInfo>(Arrays.asList(m1, m3)), new HashSet <ModuleInfo>(resultAll.allInstances())); 526 synchronized (waiter) { 527 if (! waiter[0]) { 528 waiter.wait(5000); 529 } 530 } 531 assertTrue("got lookup changes within 5 seconds", waiter[0]); 532 } 533 534 535 public void test14561() throws Exception { 536 FakeModuleInstaller installer = new FakeModuleInstaller(); 537 FakeEvents ev = new FakeEvents(); 538 ModuleManager mgr = new ModuleManager(installer, ev); 539 mgr.mutexPrivileged().enterWriteAccess(); 540 try { 541 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 542 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 543 Set <Module> m1AndM2 = new HashSet <Module>(Arrays.asList(m1, m2)); 544 mgr.enable(m1AndM2); 545 mgr.disable(m1AndM2); 546 assertEquals(Collections.EMPTY_SET, m2.getProblems()); 547 mgr.delete(m1); 548 assertEquals(1, m2.getProblems().size()); 549 assertEquals(Collections.EMPTY_LIST, mgr.simulateEnable(Collections.singleton(m2))); 550 } finally { 551 mgr.mutexPrivileged().exitWriteAccess(); 552 } 553 } 554 555 556 public void test14560() throws Exception { 557 FakeModuleInstaller installer = new FakeModuleInstaller(); 558 FakeEvents ev = new FakeEvents(); 559 ModuleManager mgr = new ModuleManager(installer, ev); 560 LoggedPCListener listener = new LoggedPCListener(); 561 mgr.addPropertyChangeListener(listener); 562 mgr.mutexPrivileged().enterWriteAccess(); 563 Module m1, m2; 564 try { 565 m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 566 m1.addPropertyChangeListener(listener); 567 m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 568 m2.addPropertyChangeListener(listener); 569 installer.delinquents.add(m1); 570 Set <Module> m1AndM2 = new HashSet <Module>(Arrays.asList(m1, m2)); 571 try { 572 mgr.enable(m1AndM2); 573 } catch (InvalidException ie) { 574 assertEquals(m1, ie.getModule()); 575 } 576 assertFalse(m1.isEnabled()); 577 } finally { 578 mgr.mutexPrivileged().exitWriteAccess(); 579 } 580 assertTrue("Got PROP_PROBLEMS on m1", listener.waitForChange(m1, Module.PROP_PROBLEMS)); 581 } 582 583 public void testPackageLoading() throws Exception { 585 FakeModuleInstaller installer = new FakeModuleInstaller(); 586 FakeEvents ev = new FakeEvents(); 587 ModuleManager mgr = new ModuleManager(installer, ev); 588 mgr.mutexPrivileged().enterWriteAccess(); 589 try { 590 tryEnablingModule(mgr, "depends-on-lib-undecl.jar"); 592 tryEnablingModule(mgr, "depends-on-lib-unvers.jar"); 593 tryEnablingModule(mgr, "depends-on-lib-vers.jar"); 594 tryEnablingModule(mgr, "depends-on-lib-vers-partial.jar"); 595 failToEnableModule(mgr, "fails-on-lib-unvers.jar"); 600 failToEnableModule(mgr, "fails-on-lib-old.jar"); 601 Module m = mgr.create(new File (jars, "depends-on-lib-undecl.jar"), null, false, false, false); 603 mgr.enable(m); 604 Class c = m.getClassLoader().loadClass("org.dol.User"); 605 Object o = c.newInstance(); 606 Field f = c.getField("val"); 607 assertEquals(42, f.getInt(o)); 608 mgr.disable(m); 609 mgr.delete(m); 610 } finally { 611 mgr.mutexPrivileged().exitWriteAccess(); 612 } 613 } 614 615 private void tryEnablingModule(ModuleManager mgr, String name) throws Exception { 616 Module m = mgr.create(new File (jars, name), null, false, false, false); 617 try { 618 mgr.enable(m); 619 mgr.disable(m); 620 } finally { 621 mgr.delete(m); 622 } 623 } 624 625 private void failToEnableModule(ModuleManager mgr, String name) throws Exception { 626 try { 627 tryEnablingModule(mgr, name); 628 fail("Was able to turn on " + name + " without complaint"); 629 } catch (InvalidException ie) { 630 } 632 } 633 634 public void testPackageDependencyMayfail() throws Exception { 635 FakeModuleInstaller installer = new FakeModuleInstaller(); 637 FakeEvents ev = new FakeEvents(); 638 ModuleManager mgr = new ModuleManager(installer, ev); 639 mgr.mutexPrivileged().enterWriteAccess(); 640 try { 641 Manifest mani; 642 JarFile jf = new JarFile (new File (jars, "simple-module.jar")); 643 try { 644 mani = jf.getManifest(); 645 } finally { 646 jf.close(); 647 } 648 649 Module toFail = mgr.create(new File (jars, "fails-on-non-existing-package.jar"), null, false, false, false); 650 Module fixed = mgr.createFixed(mani, null, this.getClass().getClassLoader()); 651 652 try { 653 mgr.enable(new HashSet <Module>(Arrays.asList(toFail, fixed))); 654 fail("Was able to turn on fails-on-non-existing-package.jar without complaint"); 655 } catch (InvalidException e) { 656 assertTrue("fails-on-non-existing-package.jar was not enabled", e.getModule() == toFail); 657 } 658 659 assertTrue("simple-module.jar was enabled", fixed.isEnabled()); 660 } finally { 661 mgr.mutexPrivileged().exitWriteAccess(); 662 } 663 } 664 665 666 public void testLocalizedManifestAttributes() throws Exception { 668 FakeModuleInstaller installer = new FakeModuleInstaller(); 669 FakeEvents ev = new FakeEvents(); 670 ModuleManager mgr = new ModuleManager(installer, ev); 671 mgr.mutexPrivileged().enterWriteAccess(); 672 Locale starting = Locale.getDefault(); 673 try { 674 Locale.setDefault(new Locale ("en", "US")); 675 File locmanijar = new File (jars, "localized-manifest.jar"); 676 assertTrue("test JAR exists: " + locmanijar, locmanijar.isFile()); Module m = mgr.create(locmanijar, null, false, false, false); 678 assertEquals("en_US display name", "Localized Manifest Module", m.getDisplayName()); 680 assertEquals("en_US bundle main attr", "value #1", m.getLocalizedAttribute("some-other-key")); 681 assertEquals("en_US bundle sub attr", "value #2", m.getLocalizedAttribute("locmani/something.txt/other-key")); 682 assertEquals("en_US bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans")); 683 assertEquals("en_US bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans")); 684 assertEquals("en_US manifest main attr", "value #3", m.getLocalizedAttribute("some-key")); 686 assertEquals("en_US manifest sub attr", "value #4", m.getLocalizedAttribute("locmani/something.txt/key")); 687 assertEquals("en_US manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans")); 688 assertEquals("en_US manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans")); 689 mgr.delete(m); 690 Locale.setDefault(new Locale ("cs", "CZ")); 692 m = mgr.create(new File (jars, "localized-manifest.jar"), null, false, false, false); 693 assertEquals("cs_CZ display name", "Modul s lokalizovan\u00FDm manifestem", m.getDisplayName()); 695 assertEquals("cs_CZ bundle main attr", "v\u00FDznam #1", m.getLocalizedAttribute("some-other-key")); 696 assertEquals("cs_CZ bundle sub attr", "v\u00FDznam #2", m.getLocalizedAttribute("locmani/something.txt/other-key")); 697 assertEquals("cs_CZ bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans")); 699 assertEquals("cs_CZ bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans")); 700 assertEquals("cs_CZ manifest main attr", "vyznam #3", m.getLocalizedAttribute("some-key")); 702 assertEquals("cs_CZ manifest sub attr", "vyznam #4", m.getLocalizedAttribute("locmani/something.txt/key")); 703 assertEquals("cs_CZ manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans")); 705 assertEquals("cs_CZ manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans")); 706 } finally { 707 mgr.mutexPrivileged().exitWriteAccess(); 708 Locale.setDefault(starting); 709 } 710 } 711 712 public void testLocalizedManifestAttributesWhileEnabled() throws Exception { 714 FakeModuleInstaller installer = new FakeModuleInstaller(); 715 FakeEvents ev = new FakeEvents(); 716 ModuleManager mgr = new ModuleManager(installer, ev); 717 mgr.mutexPrivileged().enterWriteAccess(); 718 Locale starting = Locale.getDefault(); 719 try { 720 Locale.setDefault(new Locale ("en", "US")); 721 Module m = mgr.create(new File (jars, "localized-manifest.jar"), null, false, false, false); 722 mgr.enable(m); 723 assertEquals("en_US display name", "Localized Manifest Module", m.getDisplayName()); 725 assertEquals("en_US bundle main attr", "value #1", m.getLocalizedAttribute("some-other-key")); 726 assertEquals("en_US bundle sub attr", "value #2", m.getLocalizedAttribute("locmani/something.txt/other-key")); 727 assertEquals("en_US bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans")); 728 assertEquals("en_US bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans")); 729 assertEquals("en_US manifest main attr", "value #3", m.getLocalizedAttribute("some-key")); 731 assertEquals("en_US manifest sub attr", "value #4", m.getLocalizedAttribute("locmani/something.txt/key")); 732 assertEquals("en_US manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans")); 733 assertEquals("en_US manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans")); 734 mgr.disable(m); 735 mgr.delete(m); 736 Locale.setDefault(new Locale ("cs", "CZ")); 738 m = mgr.create(new File (jars, "localized-manifest.jar"), null, false, false, false); 739 mgr.enable(m); 740 assertEquals("cs_CZ display name", "Modul s lokalizovan\u00FDm manifestem", m.getDisplayName()); 742 assertEquals("cs_CZ bundle main attr", "v\u00FDznam #1", m.getLocalizedAttribute("some-other-key")); 743 assertEquals("cs_CZ bundle sub attr", "v\u00FDznam #2", m.getLocalizedAttribute("locmani/something.txt/other-key")); 744 assertEquals("cs_CZ bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans")); 746 assertEquals("cs_CZ bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans")); 747 assertEquals("cs_CZ manifest main attr", "vyznam #3", m.getLocalizedAttribute("some-key")); 749 assertEquals("cs_CZ manifest sub attr", "vyznam #4", m.getLocalizedAttribute("locmani/something.txt/key")); 750 assertEquals("cs_CZ manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans")); 752 assertEquals("cs_CZ manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans")); 753 mgr.disable(m); 754 } finally { 755 mgr.mutexPrivileged().exitWriteAccess(); 756 Locale.setDefault(starting); 757 } 758 } 759 760 public void testLocalizedManifestAttributesClasspath() throws Exception { 762 File jar = new File (jars, "localized-manifest.jar"); 763 File ljar = new File (new File (jars, "locale"), "localized-manifest_cs.jar"); 764 Manifest mani; 765 JarFile jf = new JarFile (jar); 766 try { 767 mani = jf.getManifest(); 768 } finally { 769 jf.close(); 770 } 771 ClassLoader l = new URLClassLoader (new URL [] { 772 jar.toURL(), 774 ljar.toURL(), 775 }); 776 FakeModuleInstaller installer = new FakeModuleInstaller(); 777 FakeEvents ev = new FakeEvents(); 778 Locale starting = Locale.getDefault(); 779 try { 780 ModuleManager mgr = new ModuleManager(installer, ev); 781 mgr.mutexPrivileged().enterWriteAccess(); 782 try { 783 Locale.setDefault(new Locale ("en", "US")); 784 Module m = mgr.createFixed(mani, null, l); 785 assertEquals("en_US display name", "Localized Manifest Module", m.getDisplayName()); 787 assertEquals("en_US bundle main attr", "value #1", m.getLocalizedAttribute("some-other-key")); 788 assertEquals("en_US bundle sub attr", "value #2", m.getLocalizedAttribute("locmani/something.txt/other-key")); 789 assertEquals("en_US bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans")); 790 assertEquals("en_US bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans")); 791 assertEquals("en_US manifest main attr", "value #3", m.getLocalizedAttribute("some-key")); 793 assertEquals("en_US manifest sub attr", "value #4", m.getLocalizedAttribute("locmani/something.txt/key")); 794 assertEquals("en_US manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans")); 795 assertEquals("en_US manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans")); 796 } finally { 797 mgr.mutexPrivileged().exitWriteAccess(); 798 } 799 mgr = new ModuleManager(installer, ev); 802 mgr.mutexPrivileged().enterWriteAccess(); 803 try { 804 Locale.setDefault(new Locale ("cs", "CZ")); 806 Module m = mgr.createFixed(mani, null, l); 807 assertEquals("cs_CZ display name", "Modul s lokalizovan\u00FDm manifestem", m.getDisplayName()); 809 assertEquals("cs_CZ bundle main attr", "v\u00FDznam #1", m.getLocalizedAttribute("some-other-key")); 810 assertEquals("cs_CZ bundle sub attr", "v\u00FDznam #2", m.getLocalizedAttribute("locmani/something.txt/other-key")); 811 assertEquals("cs_CZ bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans")); 813 assertEquals("cs_CZ bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans")); 814 assertEquals("cs_CZ manifest main attr", "vyznam #3", m.getLocalizedAttribute("some-key")); 816 assertEquals("cs_CZ manifest sub attr", "vyznam #4", m.getLocalizedAttribute("locmani/something.txt/key")); 817 assertEquals("cs_CZ manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans")); 819 assertEquals("cs_CZ manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans")); 820 } finally { 821 mgr.mutexPrivileged().exitWriteAccess(); 822 } 823 } finally { 824 Locale.setDefault(starting); 825 } 826 } 827 828 public void testModulePatches() throws Exception { 830 FakeModuleInstaller installer = new FakeModuleInstaller(); 831 FakeEvents ev = new FakeEvents(); 832 ModuleManager mgr = new ModuleManager(installer, ev); 833 mgr.mutexPrivileged().enterWriteAccess(); 834 try { 835 Module m = mgr.create(new File (jars, "patchable.jar"), null, false, false, false); 836 mgr.enable(m); 837 Class c = m.getClassLoader().loadClass("pkg.subpkg.A"); 838 Field f = c.getField("val"); 839 Object o = c.newInstance(); 840 assertEquals(25, f.getInt(o)); 841 } finally { 842 mgr.mutexPrivileged().exitWriteAccess(); 843 } 844 } 845 846 public void testSimpleProvReq() throws Exception { 847 FakeModuleInstaller installer = new FakeModuleInstaller(); 848 FakeEvents ev = new FakeEvents(); 849 ModuleManager mgr = new ModuleManager(installer, ev); 850 mgr.mutexPrivileged().enterWriteAccess(); 851 try { 852 Module m1 = mgr.create(new File (jars, "prov-foo.jar"), null, false, false, false); 853 Module m2 = mgr.create(new File (jars, "req-foo.jar"), null, false, false, false); 854 assertEquals(Collections.singletonList("foo"), Arrays.asList(m1.getProvides())); 855 assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides())); 856 assertEquals(Collections.EMPTY_SET, m1.getDependencies()); 857 assertEquals(Dependency.create(Dependency.TYPE_REQUIRES, "foo"), m2.getDependencies()); 858 Map <String ,Module> modulesByName = new HashMap <String ,Module>(); 859 modulesByName.put(m1.getCodeNameBase(), m1); 860 modulesByName.put(m2.getCodeNameBase(), m2); 861 Map <String ,Set <Module>> providersOf = new HashMap <String ,Set <Module>>(); 862 providersOf.put("foo", Collections.singleton(m1)); 863 List <Module> m1m2 = Arrays.asList(m1, m2); 864 List <Module> m2m1 = Arrays.asList(m2, m1); 865 Map <Module,List <Module>> deps = Util.moduleDependencies(m1m2, modulesByName, providersOf); 866 assertNull(deps.get(m1)); 867 assertEquals(Collections.singletonList(m1), deps.get(m2)); 868 assertEquals(m2m1, Utilities.topologicalSort(m1m2, deps)); 869 assertEquals(m2m1, Utilities.topologicalSort(m2m1, deps)); 870 Set <Module> m1PlusM2 = new HashSet <Module>(); 871 m1PlusM2.add(m1); 872 m1PlusM2.add(m2); 873 List <Module> toEnable = mgr.simulateEnable(m1PlusM2); 874 assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable); 875 toEnable = mgr.simulateEnable(Collections.singleton(m2)); 876 assertEquals("correct result of simulateEnable #2", Arrays.asList(m1, m2), toEnable); 877 mgr.enable(m1PlusM2); 878 assertEquals(Arrays.asList( 879 "prepare", 880 "prepare", 881 "load" 882 ), installer.actions); 883 assertEquals(Arrays.asList( 884 m1, 885 m2, 886 Arrays.asList(m1, m2) 887 ), installer.args); 888 Class testclazz = Class.forName("org.prov_foo.Clazz", true, m1.getClassLoader()); 889 try { 890 Class.forName("org.prov_foo.Clazz", true, m2.getClassLoader()); 891 fail("Should not be able to access classes due to prov-req deps only"); 892 } catch (ClassNotFoundException cnfe) { 893 } 895 installer.clear(); 896 List <Module> toDisable = mgr.simulateDisable(Collections.singleton(m1)); 897 assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), toDisable); 898 toDisable = mgr.simulateDisable(m1PlusM2); 899 assertEquals("correct result of simulateDisable #2", Arrays.asList(m2, m1), toDisable); 900 mgr.disable(m1PlusM2); 901 assertFalse(m1.isEnabled()); 902 assertFalse(m2.isEnabled()); 903 assertEquals(Arrays.asList( 904 "unload", 905 "dispose", 906 "dispose" 907 ), installer.actions); 908 assertEquals(Arrays.asList( 909 Arrays.asList(m2, m1), 910 m2, 911 m1 912 ), installer.args); 913 } finally { 914 mgr.mutexPrivileged().exitWriteAccess(); 915 } 916 } 917 918 public void testProvReqCycles() throws Exception { 919 FakeModuleInstaller installer = new FakeModuleInstaller(); 920 FakeEvents ev = new FakeEvents(); 921 ModuleManager mgr = new ModuleManager(installer, ev); 922 mgr.mutexPrivileged().enterWriteAccess(); 923 try { 924 Module m1 = mgr.create(new File (jars, "prov-foo-req-bar.jar"), null, false, false, false); 925 Module m2 = mgr.create(new File (jars, "prov-bar-req-foo.jar"), null, false, false, false); 926 assertEquals("m1 cannot be installed because of m2", 927 Dependency.create(Dependency.TYPE_REQUIRES, "bar"), 928 m1.getProblems()); 929 assertEquals("m2 cannot be installed because of m1", 930 Dependency.create(Dependency.TYPE_REQUIRES, "foo"), 931 m2.getProblems()); 932 assertEquals("neither m1 nor m2 can be installed", 933 Collections.EMPTY_LIST, 934 mgr.simulateEnable(new HashSet <Module>(Arrays.asList(m1, m2)))); 935 mgr.delete(m2); 936 Module m3 = mgr.create(new File (jars, "prov-bar-dep-cyclic.jar"), null, false, false, false); 937 assertEquals("m1 cannot be installed because of m3", 938 Dependency.create(Dependency.TYPE_REQUIRES, "bar"), 939 m1.getProblems()); 940 assertEquals("m3 cannot be installed because of m1", 941 Dependency.create(Dependency.TYPE_MODULE, "prov_foo_req_bar"), 942 m3.getProblems()); 943 assertEquals("neither m1 nor m3 can be installed", 944 Collections.EMPTY_LIST, 945 mgr.simulateEnable(new HashSet <Module>(Arrays.asList(m1, m3)))); 946 m2 = mgr.create(new File (jars, "prov-bar-req-foo.jar"), null, false, false, false); 947 assertEquals("m2 cannot be installed because of m1", 948 Dependency.create(Dependency.TYPE_REQUIRES, "foo"), 949 m2.getProblems()); 950 Module m4 = mgr.create(new File (jars, "prov-foo.jar"), null, false, false, false); 951 assertEquals("m2 is OK with m4 here", 952 Collections.EMPTY_SET, 953 m2.getProblems()); 954 mgr.delete(m1); assertEquals("m2 and m4 can be enabled together", 956 Arrays.asList(m4, m2), 957 mgr.simulateEnable(Collections.singleton(m2))); 958 } finally { 959 mgr.mutexPrivileged().exitWriteAccess(); 960 } 961 } 962 963 public void testMultipleProvs() throws Exception { 964 FakeModuleInstaller installer = new FakeModuleInstaller(); 965 FakeEvents ev = new FakeEvents(); 966 ModuleManager mgr = new ModuleManager(installer, ev); 967 mgr.mutexPrivileged().enterWriteAccess(); 968 try { 969 Module m1 = mgr.create(new File (jars, "prov-foo.jar"), null, false, false, false); 970 Module m2 = mgr.create(new File (jars, "prov-foo-bar.jar"), null, false, false, false); 971 Module m3 = mgr.create(new File (jars, "req-foo.jar"), null, false, false, false); 972 Set <Module> m123 = new HashSet <Module>(Arrays.asList(m1, m2, m3)); 973 List <Module> toEnable = mgr.simulateEnable(Collections.singleton(m3)); 974 assertEquals("From start, turn on all providers", m123, new HashSet <Module>(toEnable)); 976 assertEquals("m3 last", m3, toEnable.get(2)); 977 assertEquals("Could request them all together too", m123, new HashSet <Module>(mgr.simulateEnable(m123))); 978 List <Module> m13 = Arrays.asList(m1, m3); 979 assertEquals("Or just m1 + m3", m13, mgr.simulateEnable(new HashSet <Module>(m13))); 980 List <Module> m23 = Arrays.asList(m2, m3); 981 assertEquals("Or just m2 + m3", m23, mgr.simulateEnable(new HashSet <Module>(m23))); 982 mgr.enable(m123); 983 assertTrue(m1.isEnabled()); 984 assertTrue(m2.isEnabled()); 985 assertTrue(m3.isEnabled()); 986 assertEquals("Can turn off one provider", 987 Collections.singletonList(m1), 988 mgr.simulateDisable(Collections.singleton(m1))); 989 Set <Module> m12 = new HashSet <Module>(Arrays.asList(m1, m2)); 990 assertEquals("Can't turn off both providers", 991 m123, 992 new HashSet <Module>(mgr.simulateDisable(m12))); 993 mgr.disable(m1); 994 assertFalse(m1.isEnabled()); 995 assertTrue(m2.isEnabled()); 996 assertTrue(m3.isEnabled()); 997 List <Module> m32 = Arrays.asList(m3, m2); 998 assertEquals("Can't turn off last provider", 999 m32, 1000 mgr.simulateDisable(Collections.singleton(m2))); 1001 mgr.disable(new HashSet <Module>(m32)); 1002 assertFalse(m1.isEnabled()); 1003 assertFalse(m2.isEnabled()); 1004 assertFalse(m3.isEnabled()); 1005 } finally { 1006 mgr.mutexPrivileged().exitWriteAccess(); 1007 } 1008 } 1009 1010 public void testProvReqUnsatisfiable() throws Exception { 1011 FakeModuleInstaller installer = new FakeModuleInstaller(); 1012 FakeEvents ev = new FakeEvents(); 1013 ModuleManager mgr = new ModuleManager(installer, ev); 1014 mgr.mutexPrivileged().enterWriteAccess(); 1015 Module m1 = createModule(mgr, "OpenIDE-Module: m1\nOpenIDE-Module-Needs: tok\n"); 1016 Module m2 = createModule(mgr, "OpenIDE-Module: m2\nOpenIDE-Module-Module-Dependencies: m1\n"); 1017 assertEquals(Collections.emptyList(), mgr.simulateEnable(Collections.singleton(m2))); 1018 Module m3 = createModule(mgr, "OpenIDE-Module: m3\nOpenIDE-Module-Provides: tok\n"); 1019 assertEquals(new HashSet <Module>(Arrays.asList(m1, m2, m3)), new HashSet <Module>(mgr.simulateEnable(Collections.singleton(m2)))); 1020 mgr = new ModuleManager(installer, ev); 1021 mgr.mutexPrivileged().enterWriteAccess(); 1022 m1 = createModule(mgr, "OpenIDE-Module: m1\nOpenIDE-Module-Requires: tok\n"); 1023 m2 = createModule(mgr, "OpenIDE-Module: m2\nOpenIDE-Module-Module-Dependencies: m1\nOpenIDE-Module-Provides: tok\n"); 1024 assertEquals(Collections.emptyList(), mgr.simulateEnable(Collections.singleton(m2))); 1025 } 1026 1027 public void testSimpleProvNeeds() throws Exception { 1028 doSimpleProvNeeds(false, false); 1029 } 1030 1031 public void testSimpleProvNeedsReversed() throws Exception { 1032 doSimpleProvNeeds(true, false); 1033 } 1034 1035 public void testSimpleSatisfiedProvRecommends() throws Exception { 1036 doSimpleProvNeeds(false, true); 1037 } 1038 1039 public void testSimpleSatisfiedProvRecommendsReversed() throws Exception { 1040 doSimpleProvNeeds(true, true); 1041 } 1042 1043 private void doSimpleProvNeeds(boolean reverseOrder, boolean recommends) throws Exception { 1044 FakeModuleInstaller installer = new FakeModuleInstaller(); 1045 FakeEvents ev = new FakeEvents(); 1046 ModuleManager mgr = new ModuleManager(installer, ev); 1047 mgr.mutexPrivileged().enterWriteAccess(); 1048 try { 1049 Module m1 = mgr.create(new File (jars, "prov-foo-depends-needs_foo.jar"), null, false, false, false); 1050 Module m2; 1051 if (recommends) { 1052 m2 = mgr.create(new File (jars, "recommends-foo.jar"), null, false, false, false); 1053 } else { 1054 m2 = mgr.create(new File (jars, "needs-foo.jar"), null, false, false, false); 1055 } 1056 assertEquals(Collections.singletonList("foo"), Arrays.asList(m1.getProvides())); 1057 assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides())); 1058 assertEquals(1, m1.getDependencies().size()); 1059 int type = recommends ? Dependency.TYPE_RECOMMENDS : Dependency.TYPE_NEEDS; 1060 assertEquals(Dependency.create(type, "foo"), m2.getDependencies()); 1061 Map <String ,Module> modulesByName = new HashMap <String ,Module>(); 1062 modulesByName.put(m1.getCodeNameBase(), m1); 1063 modulesByName.put(m2.getCodeNameBase(), m2); 1064 Map <String ,Set <Module>> providersOf = new HashMap <String ,Set <Module>>(); 1065 providersOf.put("foo", Collections.singleton(m1)); 1066 List <Module> m1m2 = Arrays.asList(m1, m2); 1067 List <Module> m2m1 = Arrays.asList(m2, m1); 1068 Map <Module,List <Module>> deps = Util.moduleDependencies(m1m2, modulesByName, providersOf); 1069 assertEquals(Collections.singletonList(m2), deps.get(m1)); 1070 1081 Set <Module> m1PlusM2 = new LinkedHashSet <Module>(); 1082 if (reverseOrder) { 1083 m1PlusM2.add(m2); 1084 m1PlusM2.add(m1); 1085 } else { 1086 m1PlusM2.add(m1); 1087 m1PlusM2.add(m2); 1088 } 1089 List <Module> toEnable = mgr.simulateEnable(m1PlusM2); 1090 assertEquals("correct result of simulateEnable", Arrays.asList(m2, m1), toEnable); 1091 toEnable = mgr.simulateEnable(Collections.singleton(m1)); 1092 assertEquals("correct result of simulateEnable #2", Arrays.asList(m2, m1), toEnable); 1093 toEnable = mgr.simulateEnable(Collections.singleton(m2)); 1094 assertEquals("correct result of simulateEnable #3", Arrays.asList(m2, m1), toEnable); 1095 mgr.enable(m1PlusM2); 1096 assertEquals(Arrays.asList( 1097 "prepare", 1098 "prepare", 1099 "load" 1100 ), installer.actions); 1101 assertEquals(Arrays.asList( 1102 m2, 1103 m1, 1104 Arrays.asList(m2, m1) 1105 ), installer.args); 1106 Class testclazz = Class.forName("org.prov_foo.Clazz", true, m1.getClassLoader()); 1107 try { 1108 Class.forName("org.prov_foo.Clazz", true, m2.getClassLoader()); 1109 fail("Should not be able to access classes due to prov-req deps only"); 1110 } catch (ClassNotFoundException cnfe) { 1111 } 1113 installer.clear(); 1114 List <Module> toDisable = mgr.simulateDisable(Collections.singleton(m1)); 1115 if (!recommends) { 1116 assertEquals("correct result of simulateDisable", Arrays.asList(m1, m2), toDisable); 1117 toDisable = mgr.simulateDisable(m1PlusM2); 1118 assertEquals("correct result of simulateDisable #2", Arrays.asList(m1, m2), toDisable); 1119 mgr.disable(m1PlusM2); 1120 assertFalse(m1.isEnabled()); 1121 assertFalse(m2.isEnabled()); 1122 assertEquals(Arrays.asList( 1123 "unload", 1124 "dispose", 1125 "dispose" 1126 ), installer.actions); 1127 assertEquals(Arrays.asList( 1128 Arrays.asList(m1, m2), 1129 m1, 1130 m2 1131 ), installer.args); 1132 } else { 1133 assertEquals("correct result of simulateDisable", Collections.singletonList(m1 ), toDisable); 1134 toDisable = mgr.simulateDisable(m1PlusM2); 1135 assertEquals("correct result of simulateDisable #2", Arrays.asList(m1, m2), toDisable); 1136 mgr.disable(m1); 1137 assertFalse(m1.isEnabled()); 1138 assertTrue(m2.isEnabled()); 1139 mgr.disable(m2); 1140 assertFalse(m2.isEnabled()); 1141 assertEquals(Arrays.asList( 1142 "unload", 1143 "dispose", 1144 "unload", 1145 "dispose" 1146 ), installer.actions); 1147 assertEquals(Arrays.asList( 1148 Collections.singletonList(m1), 1149 m1, 1150 Collections.singletonList(m2), 1151 m2 1152 ), installer.args); 1153 } 1154 } finally { 1155 mgr.mutexPrivileged().exitWriteAccess(); 1156 } 1157 } 1158 1159 public void testComplexProvNeeds() throws Exception { 1160 doComplexProvNeeds(false, false, false); 1161 } 1162 1163 public void testComplexProvNeedsReversed() throws Exception { 1164 doComplexProvNeeds(true, false, false); 1165 } 1166 1167 public void testComplexSatisfiedProvRecommends() throws Exception { 1168 doComplexProvNeeds(false, true, false); 1169 } 1170 1171 public void testComplexSatisfiedProvRecommendsReversed() throws Exception { 1172 doComplexProvNeeds(true, true, true); 1173 } 1174 1175 public void testComplexProvNeeds2() throws Exception { 1176 doComplexProvNeeds(false, false, true); 1177 } 1178 1179 public void testComplexProvNeedsReversed2() throws Exception { 1180 doComplexProvNeeds(true, false, true); 1181 } 1182 1183 public void testComplexSatisfiedProvRecommends2() throws Exception { 1184 doComplexProvNeeds(false, true, true); 1185 } 1186 1187 public void testComplexSatisfiedProvRecommendsReversed2() throws Exception { 1188 doComplexProvNeeds(true, true, true); 1189 } 1190 1191 private void doComplexProvNeeds(boolean reverseOrder, boolean recommends, boolean sndRec) throws Exception { 1192 FakeModuleInstaller installer = new FakeModuleInstaller(); 1193 FakeEvents ev = new FakeEvents(); 1194 ModuleManager mgr = new ModuleManager(installer, ev); 1195 mgr.mutexPrivileged().enterWriteAccess(); 1196 try { 1197 Module m1 = mgr.create(new File (jars, "prov-foo-depends-needs_foo.jar"), null, false, true, false); 1198 Module m2; 1199 if (recommends) { 1200 m2 = mgr.create(new File (jars, "recommends-foo.jar"), null, false, false, false); 1201 } else { 1202 m2 = mgr.create(new File (jars, "needs-foo.jar"), null, false, false, false); 1203 } 1204 Module m3 = null; 1205 if (sndRec) { 1206 String manifest = "Manifest-Version: 1.0\n" + 1207"OpenIDE-Module: snd.needs_foo\n" + 1208"OpenIDE-Module-Name: 2nd Needs foo\n" + 1209"OpenIDE-Module-Needs: foo\n"; 1210 m3 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, false, false); 1211 } else { 1212 String manifest = "Manifest-Version: 1.0\n" + 1213"OpenIDE-Module: snd.needs_foo\n" + 1214"OpenIDE-Module-Name: 2nd Needs foo\n" + 1215"OpenIDE-Module-Recommends: foo\n"; 1216 m3 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, false, false); 1217 } 1218 assertEquals(Collections.singletonList("foo"), Arrays.asList(m1.getProvides())); 1219 assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides())); 1220 assertEquals(1, m1.getDependencies().size()); 1221 int type = recommends ? Dependency.TYPE_RECOMMENDS : Dependency.TYPE_NEEDS; 1222 assertEquals(Dependency.create(type, "foo"), m2.getDependencies()); 1223 Map <String ,Module> modulesByName = new HashMap <String ,Module>(); 1224 modulesByName.put(m1.getCodeNameBase(), m1); 1225 modulesByName.put(m2.getCodeNameBase(), m2); 1226 Map <String ,Set <Module>> providersOf = new HashMap <String ,Set <Module>>(); 1227 providersOf.put("foo", Collections.singleton(m1)); 1228 List <Module> m1m2 = Arrays.asList(m1, m2); 1229 List <Module> m2m1 = Arrays.asList(m2, m1); 1230 Map <Module,List <Module>> deps = Util.moduleDependencies(m1m2, modulesByName, providersOf); 1231 assertEquals(Collections.singletonList(m2), deps.get(m1)); 1232 List <Module> toEnable = mgr.simulateEnable(Collections.singleton(m2)); 1233 assertEquals("correct result of simulateEnable", Arrays.asList(m2, m1), toEnable); 1234 1235 mgr.enable(m2); 1236 assertEquals(Arrays.asList( 1237 "prepare", 1238 "prepare", 1239 "load" 1240 ), installer.actions); 1241 assertEquals(Arrays.asList( 1242 m2, 1243 m1, 1244 Arrays.asList(m2, m1) 1245 ), installer.args); 1246 Class testclazz = Class.forName("org.prov_foo.Clazz", true, m1.getClassLoader()); 1247 try { 1248 Class.forName("org.prov_foo.Clazz", true, m2.getClassLoader()); 1249 fail("Should not be able to access classes due to prov-req deps only"); 1250 } catch (ClassNotFoundException cnfe) { 1251 } 1253 1254 mgr.enable(m3); 1255 assertTrue("m3 enabled1", m3.isEnabled()); 1256 1257 installer.clear(); 1258 List <Module> toDisable = mgr.simulateDisable(Collections.singleton(m3)); 1259 if (!recommends) { 1260 mgr.disable(m3); 1261 assertFalse("M3 enabled", m3.isEnabled()); 1262 assertTrue("Provider enabled", m1.isEnabled()); 1263 assertTrue(m2.isEnabled()); 1264 assertEquals(Arrays.asList( 1265 "unload", 1266 "dispose" 1267 ), installer.actions); 1268 assertEquals(Arrays.asList( 1269 Collections.singletonList( m3 ), 1270 m3 1271 ), installer.args); 1272 } else { 1273 mgr.disable(m3); 1274 assertFalse(m3.isEnabled()); 1275 assertTrue(m2.isEnabled()); 1276 assertTrue(m1.isEnabled()); 1277 assertEquals(Arrays.asList( 1278 "unload", 1279 "dispose" 1280 ), installer.actions); 1281 assertEquals(Arrays.asList( 1282 Collections.singletonList(m3), 1283 m3 1284 ), installer.args); 1285 } 1286 } finally { 1287 mgr.mutexPrivileged().exitWriteAccess(); 1288 } 1289 } 1290 1291 public void testRecommendsWithoutAProvider() throws Exception { 1292 FakeModuleInstaller installer = new FakeModuleInstaller(); 1293 FakeEvents ev = new FakeEvents(); 1294 ModuleManager mgr = new ModuleManager(installer, ev); 1295 mgr.mutexPrivileged().enterWriteAccess(); 1296 try { 1297 Module m2 = mgr.create(new File (jars, "recommends-foo.jar"), null, false, false, false); 1298 assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides())); 1299 assertEquals(Dependency.create(Dependency.TYPE_RECOMMENDS, "foo"), m2.getDependencies()); 1300 Map <String ,Module> modulesByName = new HashMap <String ,Module>(); 1301 modulesByName.put(m2.getCodeNameBase(), m2); 1302 Map <String ,Set <Module>> providersOf = new HashMap <String ,Set <Module>>(); 1303 List <Module> m2List = Collections.singletonList( m2 ); 1304 Map <Module,List <Module>> deps = Util.moduleDependencies(m2List, modulesByName, providersOf); 1305 assertEquals(null, deps.get(m2)); 1306 1307 List <Module> toEnable = mgr.simulateEnable(new HashSet <Module>(m2List)); 1308 assertEquals("correct result of simulateEnable", Collections.singletonList(m2), toEnable); 1309 mgr.enable(new HashSet <Module>(m2List)); 1310 assertEquals(Arrays.asList( 1311 "prepare", 1312 "load" 1313 ), installer.actions); 1314 assertEquals(Arrays.asList( 1315 m2, 1316 Collections.singletonList(m2) 1318 ), installer.args); 1319 installer.clear(); 1320 List <Module> toDisable = mgr.simulateDisable(Collections.singleton(m2)); 1321 assertEquals("correct result of simulateDisable", Collections.singletonList(m2), toDisable); 1322 mgr.disable(m2); 1323 assertFalse(m2.isEnabled()); 1324 assertEquals(Arrays.asList( 1325 "unload", 1326 "dispose" 1327 ), installer.actions); 1328 assertEquals(Arrays.asList( 1329 Collections.singletonList(m2), 1330 m2 1332 ), installer.args); 1333 } finally { 1334 mgr.mutexPrivileged().exitWriteAccess(); 1335 } 1336 } 1337 1338 public void testNeedsWithAProviderWithoutAProvider() throws Exception { 1339 doRecommendsWithAProviderWithoutAProvider(false); 1340 } 1341 1342 public void testRecommendsWithAProviderWithoutAProvider() throws Exception { 1343 doRecommendsWithAProviderWithoutAProvider(true); 1344 } 1345 1346 private void doRecommendsWithAProviderWithoutAProvider(boolean recommends) throws Exception { 1347 FakeModuleInstaller installer = new FakeModuleInstaller(); 1349 FakeEvents ev = new FakeEvents(); 1350 ModuleManager mgr = new ModuleManager(installer, ev); 1351 mgr.mutexPrivileged().enterWriteAccess(); 1352 try { 1353 Module m2 = mgr.create(new File (jars, "recommends-foo.jar"), null, false, false, false); 1354 assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides())); 1355 1356 Module m1; 1357 { 1358 String manifest = "Manifest-Version: 1.0\n" + 1359"OpenIDE-Module: snd.provides.foo\n" + 1360"OpenIDE-Module-Name: Provides foo\n" + 1361"OpenIDE-Module-Provides: foo\n" + 1362"OpenIDE-Module-Needs: bla\n"; 1363 m1 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, true, false); 1364 1365 } 1366 assertEquals(Dependency.create(Dependency.TYPE_RECOMMENDS, "foo"), m2.getDependencies()); 1367 Map <String ,Module> modulesByName = new HashMap <String ,Module>(); 1368 modulesByName.put(m2.getCodeNameBase(), m2); 1369 Map <String ,Set <Module>> providersOf = new HashMap <String ,Set <Module>>(); 1370 List <Module> m2List = Collections.singletonList(m2); 1371 Map <Module,List <Module>> deps = Util.moduleDependencies(m2List, modulesByName, providersOf); 1372 assertEquals(null, deps.get(m2)); 1373 1374 List <Module> toEnable = mgr.simulateEnable(new HashSet <Module>(m2List)); 1375 assertEquals("cannot enable while provider of bla is missing", Collections.singletonList(m2), toEnable); 1376 1377 1378 1385 1386 Module m3; 1387 { 1388 String manifest = "Manifest-Version: 1.0\n" + 1389"OpenIDE-Module: snd.provides.bar\n" + 1390"OpenIDE-Module-Name: Provides bar\n" + 1391"OpenIDE-Module-Provides: bla\n"; 1392 m3 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, true, false); 1393 } 1394 1395 Set allThreeModules = new HashSet <Module>(Arrays.asList(m1, m3, m2)); 1396 1397 toEnable = mgr.simulateEnable(new HashSet <Module>(m2List)); 1398 assertEquals("all 3 need to be enabled", allThreeModules, new HashSet <Module>(toEnable)); 1399 1400 mgr.enable(new HashSet <Module>(m2List)); 1401 assertEquals(Arrays.asList( 1402 "prepare", 1403 "prepare", 1404 "prepare", 1405 "load" 1406 ), installer.actions); 1407 installer.clear(); 1408 List <Module> toDisable = mgr.simulateDisable(Collections.singleton(m2)); 1409 assertEquals("correct result of simulateDisable", allThreeModules, new HashSet <Module>(toDisable)); 1410 mgr.disable(m2); 1411 assertFalse(m2.isEnabled()); 1412 assertEquals(Arrays.asList( 1413 "unload", 1414 "dispose", 1415 "dispose", 1416 "dispose" 1417 ), installer.actions); 1418 } finally { 1419 mgr.mutexPrivileged().exitWriteAccess(); 1420 } 1421 } 1422 1423 public void testMultipleReqs() throws Exception { 1424 FakeModuleInstaller installer = new FakeModuleInstaller(); 1425 FakeEvents ev = new FakeEvents(); 1426 ModuleManager mgr = new ModuleManager(installer, ev); 1427 mgr.mutexPrivileged().enterWriteAccess(); 1428 try { 1429 Module m1 = mgr.create(new File (jars, "prov-foo.jar"), null, false, false, false); 1430 Module m2 = mgr.create(new File (jars, "prov-baz.jar"), null, false, false, false); 1431 Module m3 = mgr.create(new File (jars, "req-foo-baz.jar"), null, false, false, false); 1432 Set <Module> m123 = new HashSet <Module>(Arrays.asList(m1, m2, m3)); 1433 assertEquals(m123, new HashSet <Module>(mgr.simulateEnable(Collections.singleton(m3)))); 1434 mgr.enable(m123); 1435 assertEquals(Arrays.asList(m3, m1), mgr.simulateDisable(Collections.singleton(m1))); 1436 assertEquals(Arrays.asList(m3, m2), mgr.simulateDisable(Collections.singleton(m2))); 1437 } finally { 1438 mgr.mutexPrivileged().exitWriteAccess(); 1439 } 1440 } 1441 1442 public void testEagerReq() throws Exception { 1443 FakeModuleInstaller installer = new FakeModuleInstaller(); 1444 FakeEvents ev = new FakeEvents(); 1445 ModuleManager mgr = new ModuleManager(installer, ev); 1446 mgr.mutexPrivileged().enterWriteAccess(); 1447 try { 1448 Module m1 = mgr.create(new File (jars, "prov-foo.jar"), null, false, false, false); 1449 Module m2 = mgr.create(new File (jars, "prov-baz.jar"), null, false, false, false); 1450 Module m3 = mgr.create(new File (jars, "req-foo-baz.jar"), null, false, false, true); 1451 assertEquals(Collections.singletonList(m1), 1452 mgr.simulateEnable(Collections.singleton(m1))); 1453 assertEquals(Collections.singletonList(m2), 1454 mgr.simulateEnable(Collections.singleton(m2))); 1455 Set <Module> m12 = new HashSet <Module>(Arrays.asList(m1, m2)); 1456 Set <Module> m123 = new HashSet <Module>(Arrays.asList(m1, m2, m3)); 1457 assertEquals(m123, new HashSet <Module>(mgr.simulateEnable(m12))); 1458 mgr.enable(m12); 1459 assertTrue(m3.isEnabled()); 1460 assertEquals(Arrays.asList(m3, m1), 1461 mgr.simulateDisable(Collections.singleton(m1))); 1462 assertEquals(Arrays.asList(m3, m2), 1463 mgr.simulateDisable(Collections.singleton(m2))); 1464 assertEquals(m123, 1465 new HashSet <Module>(mgr.simulateDisable(m12))); 1466 mgr.disable(m12); 1467 assertFalse(m3.isEnabled()); 1468 } finally { 1469 mgr.mutexPrivileged().exitWriteAccess(); 1470 } 1471 } 1472 1473 public void testAutoloadProv() throws Exception { 1474 FakeModuleInstaller installer = new FakeModuleInstaller(); 1475 FakeEvents ev = new FakeEvents(); 1476 ModuleManager mgr = new ModuleManager(installer, ev); 1477 mgr.mutexPrivileged().enterWriteAccess(); 1478 try { 1479 Module m1 = mgr.create(new File (jars, "prov-foo.jar"), null, false, true, false); 1480 Module m2 = mgr.create(new File (jars, "req-foo.jar"), null, false, false, false); 1481 assertEquals(Arrays.asList(m1, m2), 1482 mgr.simulateEnable(Collections.singleton(m2))); 1483 mgr.enable(m2); 1484 assertTrue(m1.isEnabled()); 1485 assertEquals(Arrays.asList(m2, m1), 1486 mgr.simulateDisable(Collections.singleton(m2))); 1487 mgr.disable(m2); 1488 assertFalse(m1.isEnabled()); 1489 } finally { 1490 mgr.mutexPrivileged().exitWriteAccess(); 1491 } 1492 } 1493 1494 public void testWeirdRecursion() throws Exception { 1495 FakeModuleInstaller installer = new FakeModuleInstaller(); 1496 FakeEvents ev = new FakeEvents(); 1497 ModuleManager mgr = new ModuleManager(installer, ev); 1498 mgr.mutexPrivileged().enterWriteAccess(); 1499 try { 1500 Module m2 = mgr.create(new File (jars, "prov-bar-req-foo.jar"), null, false, true, false); 1502 Module m3 = mgr.create(new File (jars, "prov-foo-bar.jar"), null, false, false, false); 1503 Module m4 = mgr.create(new File (jars, "prov-foo-req-bar.jar"), null, false, false, true); 1504 assertEquals("m2 should not be enabled - m4 might ask for it but m3 already has bar", 1505 new HashSet <Module>(Arrays.asList(m3, m4)), 1506 new HashSet <Module>(mgr.simulateEnable(Collections.singleton(m3)))); 1507 } finally { 1508 mgr.mutexPrivileged().exitWriteAccess(); 1509 } 1510 } 1511 1512 public void testLackOfOrderSensitivity() throws Exception { 1513 String [] moduleNames = new String [] { 1514 "simple-module.jar", 1515 "depends-on-simple-module.jar", 1516 "dep-on-dep-on-simple.jar", 1517 "prov-foo.jar", 1518 "prov-baz.jar", 1519 "prov-foo-bar.jar", 1520 "req-foo.jar", 1521 "req-foo-baz.jar", 1522 "prov-bar-req-foo.jar", 1523 "prov-foo-req-bar.jar", 1524 }; 1525 Set <String > noDepsNames = new HashSet <String >(Arrays.asList( 1527 "simple-module.jar", 1528 "prov-foo.jar", 1529 "prov-baz.jar", 1530 "prov-foo-bar.jar" 1531 )); 1532 List <String > freeModules = new ArrayList <String >(Arrays.asList(moduleNames)); 1533 int count = 100; Random r = new Random (count * 17 + 113); 1535 FakeModuleInstaller installer = new FakeModuleInstaller(); 1536 FakeEvents ev = new FakeEvents(); 1537 ModuleManager mgr = new ModuleManager(installer, ev); 1538 mgr.mutexPrivileged().enterWriteAccess(); 1539 try { 1540 int i = 0; 1541 while (i < count) { 1542 Util.err.info("testLackOfOrderSensitivity round #" + i); 1543 switch (r.nextInt(11)) { 1544 case 0: 1545 case 1: 1546 case 2: 1547 Util.err.info("Add a regular module"); 1548 if (!freeModules.isEmpty()) { 1549 String name = freeModules.remove(r.nextInt(freeModules.size())); 1550 mgr.create(new File (jars, name), null, false, false, false); 1551 i++; 1552 } 1553 break; 1554 case 3: 1555 Util.err.info("Add an autoload"); 1556 if (!freeModules.isEmpty()) { 1557 String name = freeModules.remove(r.nextInt(freeModules.size())); 1558 mgr.create(new File (jars, name), null, false, true, false); 1559 i++; 1560 } 1561 break; 1562 case 4: 1563 Util.err.info("Add an eager module"); 1564 if (!freeModules.isEmpty()) { 1565 String name = freeModules.remove(r.nextInt(freeModules.size())); 1566 if (!noDepsNames.contains(name)) { 1567 Module m = mgr.create(new File (jars, name), null, false, false, true); 1568 i++; 1569 } 1570 } 1571 break; 1572 case 5: 1573 case 6: 1574 Util.err.info("Remove a disabled module"); 1575 List <Module> disabled = new ArrayList <Module>(moduleNames.length); 1576 for (Module m : mgr.getModules()) { 1577 if (!m.isEnabled()) { 1578 disabled.add(m); 1579 } 1580 } 1581 if (!disabled.isEmpty()) { 1582 Module m = disabled.get(r.nextInt(disabled.size())); 1583 mgr.delete(m); 1584 freeModules.add(m.getJarFile().getName()); 1585 i++; 1586 } 1587 break; 1588 case 7: 1589 case 8: 1590 Util.err.info("Enable some set of modules"); 1591 List <Module> candidates = new ArrayList <Module>(moduleNames.length); 1592 for (Module m : mgr.getModules()) { 1593 if (!m.isEnabled() && !m.isAutoload() && !m.isEager() && r.nextBoolean()) { 1594 candidates.add(m); 1595 } 1596 } 1597 if (!candidates.isEmpty()) { 1598 Collections.shuffle(candidates, r); 1599 Set <Module> candidatesSet = new LinkedHashSet <Module>(candidates); 1600 assertEquals("OrderPreservingSet works", candidates, new ArrayList <Module>(candidatesSet)); 1601 List <Module> toEnable1 = mgr.simulateEnable(candidatesSet); 1604 Collections.shuffle(candidates, r); 1606 List <Module> toEnable2 = mgr.simulateEnable(new LinkedHashSet <Module>(candidates)); 1607 Set <Module> s1 = new HashSet <Module>(toEnable1); 1608 Set <Module> s2 = new HashSet <Module>(toEnable2); 1609 assertEquals("Order preserved", s1, s2); 1610 Iterator <Module> it = s1.iterator(); 1611 while (it.hasNext()) { 1612 Module m = it.next(); 1613 if (m.isAutoload() || m.isEager()) { 1614 it.remove(); 1615 } 1616 } 1617 mgr.enable(s1); 1618 i++; 1619 } 1620 break; 1621 case 9: 1622 case 10: 1623 Util.err.info("Disable some set of modules"); 1624 candidates = new ArrayList <Module>(moduleNames.length); 1625 for (Module m : mgr.getModules()) { 1626 if (m.isEnabled() && !m.isAutoload() && !m.isEager() && r.nextBoolean()) { 1627 candidates.add(m); 1628 } 1629 } 1630 if (!candidates.isEmpty()) { 1631 Collections.shuffle(candidates, r); 1632 List <Module> toDisable1 = mgr.simulateDisable(new LinkedHashSet <Module>(candidates)); 1634 Collections.shuffle(candidates, r); 1636 List <Module> toDisable2 = mgr.simulateDisable(new LinkedHashSet <Module>(candidates)); 1638 Set <Module> s1 = new HashSet <Module>(toDisable1); 1639 Set <Module> s2 = new HashSet <Module>(toDisable2); 1640 assertEquals("Order preserved", s1, s2); 1641 Iterator <Module> it = s1.iterator(); 1642 while (it.hasNext()) { 1643 Module m = it.next(); 1644 if (m.isAutoload() || m.isEager()) { 1645 it.remove(); 1646 } 1647 } 1648 mgr.disable(s1); 1649 i++; 1650 } 1651 break; 1652 default: 1653 throw new IllegalStateException (); 1654 } 1655 } 1656 } finally { 1657 mgr.mutexPrivileged().exitWriteAccess(); 1658 } 1659 } 1660 1685 1686 public void testRelVersRanges() throws Exception { 1687 FakeModuleInstaller installer = new FakeModuleInstaller(); 1688 FakeEvents ev = new FakeEvents(); 1689 ModuleManager mgr = new ModuleManager(installer, ev); 1690 mgr.mutexPrivileged().enterWriteAccess(); 1691 try { 1692 Module base = mgr.create(new File (jars, "rel-ver-2.jar"), null, false, false, false); 1693 String [] depNames = new String [] { 1694 "dep-on-relvertest-1.jar", "dep-on-relvertest-1-2.jar", "dep-on-relvertest-2.jar", "dep-on-relvertest-2-3.jar", "dep-on-relvertest-2-3-late.jar", "dep-on-relvertest-2-impl.jar", "dep-on-relvertest-2-impl-wrong.jar", "dep-on-relvertest-2-late.jar", "dep-on-relvertest-3-4.jar", "dep-on-relvertest-some.jar", }; 1705 Module[] deps = new Module[depNames.length]; 1706 for (int i = 0; i < deps.length; i++) { 1707 deps[i] = mgr.create(new File (jars, depNames[i]), null, false, false, false); 1708 } 1709 Set <Module> all = new HashSet <Module>(); 1710 all.add(base); 1711 all.addAll(Arrays.asList(deps)); 1712 Set <Module> ok = new HashSet <Module>(); 1713 ok.add(base); 1714 ok.add(deps[1]); 1716 ok.add(deps[2]); 1717 ok.add(deps[3]); 1718 ok.add(deps[5]); 1720 assertEquals(ok, new HashSet <Module>(mgr.simulateEnable(all))); 1725 } finally { 1726 mgr.mutexPrivileged().exitWriteAccess(); 1727 } 1728 } 1729 1730 public void testDisableAgainstRelVersRange() throws Exception { 1731 FakeModuleInstaller installer = new FakeModuleInstaller(); 1733 FakeEvents ev = new FakeEvents(); 1734 ModuleManager mgr = new ModuleManager(installer, ev); 1735 mgr.mutexPrivileged().enterWriteAccess(); 1736 try { 1737 Module base = mgr.create(new File (jars, "rel-ver-2.jar"), null, false, true, false); 1738 Module dep1 = mgr.create(new File (jars, "dep-on-relvertest-2.jar"), null, false, false, false); 1739 Module dep2 = mgr.create(new File (jars, "dep-on-relvertest-1-2-nospec.jar"), null, false, false, false); 1740 Set <Module> all = new HashSet <Module>(); 1741 all.add(dep1); 1742 all.add(dep2); 1743 mgr.enable(all); 1744 all.add(base); 1745 assertEquals("turn on autoload w/ both deps OK", all, mgr.getEnabledModules()); 1746 Set <Module> dep2only = Collections.singleton(dep2); 1747 assertEquals("intend to disable only dep2", dep2only, new HashSet <Module>(mgr.simulateDisable(dep2only))); 1748 mgr.disable(dep2only); 1749 all.remove(dep2); 1750 assertEquals("removed just dep2, not autoload used by dep1", all, mgr.getEnabledModules()); 1751 mgr.disable(Collections.singleton(dep1)); 1752 assertEquals("now all gone", Collections.EMPTY_SET, mgr.getEnabledModules()); 1753 } finally { 1754 mgr.mutexPrivileged().exitWriteAccess(); 1755 } 1756 } 1757 1758 1761 public void testModuleDeletion() throws Exception { 1762 FakeModuleInstaller installer = new FakeModuleInstaller(); 1763 FakeEvents ev = new FakeEvents(); 1764 ModuleManager mgr = new ModuleManager(installer, ev); 1765 1766 clearWorkDir(); 1767 File jar = new File (getWorkDir(), "copy-of-simple-module.jar"); 1768 copy(new File (jars, "simple-module.jar"), jar); 1769 1770 mgr.mutexPrivileged().enterWriteAccess(); 1771 try { 1772 Module m = mgr.create(jar, null, false, false, false); 1773 mgr.enable(m); 1774 Class c = m.getClassLoader().loadClass("org.foo.Something"); 1775 URL u = m.getClassLoader().getResource("org/foo/Something.class"); 1776 URLConnection uc = u.openConnection(); 1777 assertTrue("using JarURLConnection", uc instanceof JarURLConnection ); 1778 uc.connect(); 1779 mgr.disable(m); 1780 mgr.delete(m); 1781 1782 WeakReference <Class > refC = new WeakReference <Class >(c); 1783 WeakReference <URL > refU = new WeakReference <URL >(u); 1784 WeakReference <URLConnection > refUC = new WeakReference <URLConnection >(uc); 1785 1786 c = null; 1787 u = null; 1788 uc = null; 1789 1790 assertGC ("Module class can go away", refC); 1791 assertGC ("Module url", refU); 1792 assertGC ("Module connection ", refUC); 1793 } finally { 1794 mgr.mutexPrivileged().exitWriteAccess(); 1795 } 1796 1797 assertTrue("could delete JAR file", jar.delete()); 1798 } 1799 1800 1803 public void testContextClassLoader() throws Exception { 1804 FakeModuleInstaller installer = new FakeModuleInstaller(); 1805 FakeEvents ev = new FakeEvents(); 1806 final ModuleManager mgr = new ModuleManager(installer, ev); 1807 mgr.mutexPrivileged().enterWriteAccess(); 1808 final Object sleepForever = "sleepForever"; 1810 try { 1811 final Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 1812 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 1813 ClassLoader l1 = mgr.getClassLoader(); 1814 assertEquals(l1, Thread.currentThread().getContextClassLoader()); 1815 mgr.enable(m1); 1816 ClassLoader l2 = mgr.getClassLoader(); 1817 assertTrue(l1 == l2); 1818 assertEquals(l2, Thread.currentThread().getContextClassLoader()); 1819 mgr.enable(m2); 1820 ClassLoader l3 = mgr.getClassLoader(); 1821 assertTrue(l1 == l3); 1822 assertEquals(l3, Thread.currentThread().getContextClassLoader()); 1823 mgr.disable(m2); 1824 ClassLoader l4 = mgr.getClassLoader(); 1825 assertTrue(l1 != l4); 1826 assertEquals(l4, Thread.currentThread().getContextClassLoader()); 1827 final Thread [] t23 = new Thread [2]; 1828 final ClassLoader [] lx = new ClassLoader [] {new URLClassLoader (new URL [0])}; 1829 final Object finishT1 = "finishT1"; 1831 Thread t1 = new Thread ("custom thread #1") { 1832 public void run() { 1833 synchronized (finishT1) { 1834 t23[0] = new Thread ("custom thread #2") { 1835 public void run() { 1836 synchronized (sleepForever) { 1837 try { 1838 sleepForever.wait(); 1839 } catch (InterruptedException ie) { 1840 throw new Error (ie.toString()); 1841 } 1842 } 1843 } 1844 }; 1845 t23[0].start(); 1846 Thread.currentThread().setContextClassLoader(lx[0]); 1847 mgr.disable(m1); 1848 t23[1] = new Thread ("custom thread #3") { 1849 public void run() { 1850 synchronized (sleepForever) { 1851 try { 1852 sleepForever.wait(); 1853 } catch (InterruptedException ie) { 1854 throw new Error (ie.toString()); 1855 } 1856 } 1857 } 1858 }; 1859 t23[1].start(); 1860 finishT1.notify(); 1861 } 1862 synchronized (sleepForever) { 1863 try { 1864 sleepForever.wait(); 1865 } catch (InterruptedException ie) { 1866 throw new Error (ie.toString()); 1867 } 1868 } 1869 } 1870 }; 1871 t1.start(); 1872 synchronized (finishT1) { 1873 if (t23[1] == null) { 1874 finishT1.wait(); 1875 assertNotNull(t23[1]); 1876 } 1877 } 1878 assertFalse(m1.isEnabled()); 1879 ClassLoader l5 = mgr.getClassLoader(); 1880 assertTrue(l1 != l5); 1881 assertTrue(l4 != l5); 1882 assertEquals(l5, Thread.currentThread().getContextClassLoader()); 1883 assertTrue(t1.isAlive()); 1885 assertEquals(lx[0], t1.getContextClassLoader()); 1886 assertTrue(t23[0].isAlive()); 1888 assertEquals(l5, t23[0].getContextClassLoader()); 1889 assertTrue(t23[1].isAlive()); 1891 assertEquals(lx[0], t23[1].getContextClassLoader()); 1892 mgr.enable(m1); 1893 mgr.disable(m1); 1894 ClassLoader l6 = mgr.getClassLoader(); 1895 assertTrue(l1 != l6); 1896 assertTrue(l4 != l6); 1897 assertTrue(l5 != l6); 1898 assertEquals(l6, Thread.currentThread().getContextClassLoader()); 1899 assertEquals(lx[0], t1.getContextClassLoader()); 1900 assertEquals(l6, t23[0].getContextClassLoader()); 1901 assertEquals(lx[0], t23[1].getContextClassLoader()); 1902 } finally { 1903 synchronized (sleepForever) { 1904 sleepForever.notifyAll(); 1905 } 1906 mgr.mutexPrivileged().exitWriteAccess(); 1907 } 1908 } 1909 1910 1913 public void testDependOnTwoFixedModules() throws Exception { 1914 FakeModuleInstaller installer = new FakeModuleInstaller(); 1915 FakeEvents ev = new FakeEvents(); 1916 ModuleManager mgr = new ModuleManager(installer, ev); 1917 mgr.mutexPrivileged().enterWriteAccess(); 1918 try { 1919 File j1 = new File (jars, "simple-module.jar"); 1920 File j2 = new File (jars, "depends-on-simple-module.jar"); 1921 File j3 = new File (jars, "dep-on-two-modules.jar"); 1922 URLClassLoader l = new URLClassLoader (new URL [] {j1.toURL(), j2.toURL()}); 1923 Manifest mani1, mani2; 1924 JarFile j = new JarFile (j1); 1925 try { 1926 mani1 = j.getManifest(); 1927 } finally { 1928 j.close(); 1929 } 1930 j = new JarFile (j2); 1931 try { 1932 mani2 = j.getManifest(); 1933 } finally { 1934 j.close(); 1935 } 1936 Module m1 = mgr.createFixed(mani1, null, l); 1937 Module m2 = mgr.createFixed(mani2, null, l); 1938 Module m3 = mgr.create(j3, null, false, false, false); 1939 mgr.enable(new HashSet <Module>(Arrays.asList(m1, m2, m3))); 1940 } finally { 1941 mgr.mutexPrivileged().exitWriteAccess(); 1942 } 1943 } 1944 1945 1948 public void testPackageExports() throws Exception { 1949 ModuleManager mgr = new ModuleManager(new FakeModuleInstaller(), new FakeEvents()); 1950 mgr.mutexPrivileged().enterWriteAccess(); 1951 try { 1952 Module m1 = mgr.create(new File (jars, "api-mod-export-all.jar"), null, false, false, false); 1953 Module m2 = mgr.create(new File (jars, "uses-api-simple-dep.jar"), null, false, false, false); 1954 mgr.enable(m1); 1955 mgr.enable(m2); 1956 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 1957 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 1958 mgr.disable(m2); 1959 mgr.disable(m1); 1960 mgr.delete(m2); 1961 mgr.delete(m1); 1962 m1 = mgr.create(new File (jars, "api-mod-export-none.jar"), null, false, false, false); 1963 m2 = mgr.create(new File (jars, "uses-api-simple-dep.jar"), null, false, false, false); 1964 mgr.enable(m1); 1965 mgr.enable(m2); 1966 try { 1967 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 1968 fail(); 1969 } catch (NoClassDefFoundError e) {} 1970 try { 1971 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 1972 fail(); 1973 } catch (NoClassDefFoundError e) {} 1974 assertNotNull(mgr.getClassLoader().getResource("usesapi/UsesImplClass.class")); 1975 assertNotNull(mgr.getClassLoader().getResource("org/netbeans/api/foo/PublicClass.class")); 1976 assertNotNull(mgr.getClassLoader().getResource("org/netbeans/modules/foo/ImplClass.class")); 1977 mgr.disable(m2); 1978 mgr.disable(m1); 1979 mgr.delete(m2); 1980 mgr.delete(m1); 1981 m1 = mgr.create(new File (jars, "api-mod-export-none.jar"), null, false, false, false); 1982 m2 = mgr.create(new File (jars, "uses-api-spec-dep.jar"), null, false, false, false); 1983 mgr.enable(m1); 1984 mgr.enable(m2); 1985 try { 1986 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 1987 fail(); 1988 } catch (NoClassDefFoundError e) {} 1989 try { 1990 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 1991 fail(); 1992 } catch (NoClassDefFoundError e) {} 1993 mgr.disable(m2); 1994 mgr.disable(m1); 1995 mgr.delete(m2); 1996 mgr.delete(m1); 1997 m1 = mgr.create(new File (jars, "api-mod-export-none.jar"), null, false, false, false); 1998 m2 = mgr.create(new File (jars, "uses-api-impl-dep.jar"), null, false, false, false); 1999 mgr.enable(m1); 2000 mgr.enable(m2); 2001 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2002 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2003 mgr.disable(m2); 2004 mgr.disable(m1); 2005 mgr.delete(m2); 2006 mgr.delete(m1); 2007 m1 = mgr.create(new File (jars, "api-mod-export-api.jar"), null, false, false, false); 2008 m2 = mgr.create(new File (jars, "uses-api-simple-dep.jar"), null, false, false, false); 2009 assertEquals("api-mod-export-api.jar can be enabled", Collections.EMPTY_SET, m1.getProblems()); 2010 mgr.enable(m1); 2011 assertEquals("uses-api-simple-dep.jar can be enabled", Collections.EMPTY_SET, m2.getProblems()); 2012 mgr.enable(m2); 2013 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2014 try { 2015 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2016 fail(); 2017 } catch (NoClassDefFoundError e) {} 2018 mgr.disable(m2); 2019 mgr.disable(m1); 2020 mgr.delete(m2); 2021 mgr.delete(m1); 2022 m1 = mgr.create(new File (jars, "api-mod-export-api.jar"), null, false, false, false); 2023 m2 = mgr.create(new File (jars, "uses-api-spec-dep.jar"), null, false, false, false); 2024 mgr.enable(m1); 2025 mgr.enable(m2); 2026 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2027 try { 2028 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2029 fail(); 2030 } catch (NoClassDefFoundError e) {} 2031 mgr.disable(m2); 2032 mgr.disable(m1); 2033 mgr.delete(m2); 2034 mgr.delete(m1); 2035 m1 = mgr.create(new File (jars, "api-mod-export-api.jar"), null, false, false, false); 2036 m2 = mgr.create(new File (jars, "uses-api-impl-dep.jar"), null, false, false, false); 2037 mgr.enable(m1); 2038 mgr.enable(m2); 2039 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2040 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2041 mgr.disable(m2); 2042 mgr.disable(m1); 2043 mgr.delete(m2); 2044 mgr.delete(m1); 2045 } finally { 2049 mgr.mutexPrivileged().exitWriteAccess(); 2050 } 2051 } 2052 2053 2060 public void testIndirectPackageExports() throws Exception { 2061 ModuleManager mgr = new ModuleManager(new FakeModuleInstaller(), new FakeEvents()); 2062 mgr.mutexPrivileged().enterWriteAccess(); 2063 try { 2064 Module m1 = mgr.create(new File (jars, "api-mod-export-api.jar"), null, false, false, false); 2065 Module m2 = mgr.create(new File (jars, "uses-and-exports-api.jar"), null, false, false, false); 2066 Module m3 = mgr.create(new File (jars, "uses-api-transitively.jar"), null, false, false, false); 2067 Module m4 = mgr.create(new File (jars, "uses-api-directly.jar"), null, false, false, false); 2068 assertEquals("api-mod-export-api.jar had no problems", Collections.EMPTY_SET, m1.getProblems()); 2069 assertEquals("uses-and-exports-api.jar had no problems", Collections.EMPTY_SET, m2.getProblems()); 2070 assertEquals("uses-api-transitively.jar had no problems", Collections.EMPTY_SET, m3.getProblems()); 2071 assertEquals("uses-api-directly.jar had no problems", Collections.EMPTY_SET, m4.getProblems()); 2072 mgr.enable(new HashSet <Module>(Arrays.asList(m1, m2, m3, m4))); 2073 m4.getClassLoader().loadClass("usesapitrans.UsesDirectAPI").newInstance(); 2074 m4.getClassLoader().loadClass("usesapitrans.UsesIndirectAPI").newInstance(); 2075 m3.getClassLoader().loadClass("usesapitrans.UsesDirectAPI").newInstance(); 2076 try { 2077 m3.getClassLoader().loadClass("usesapitrans.UsesIndirectAPI").newInstance(); 2078 fail("Should not be able to use a transitive API class with no direct dependency"); 2079 } catch (NoClassDefFoundError e) {} 2080 mgr.disable(new HashSet <Module>(Arrays.asList(m1, m2, m3, m4))); 2081 mgr.delete(m4); 2082 mgr.delete(m3); 2083 mgr.delete(m2); 2084 mgr.delete(m1); 2085 } finally { 2086 mgr.mutexPrivileged().exitWriteAccess(); 2087 } 2088 } 2089 2090 public void testPublicPackagesCanBeExportedToSelectedFriendsOnlyIssue54123 () throws Exception { 2091 ModuleManager mgr = new ModuleManager(new FakeModuleInstaller(), new FakeEvents()); 2092 mgr.mutexPrivileged().enterWriteAccess(); 2093 try { 2094 Module m1 = mgr.create(new File (jars, "api-mod-export-friend.jar"), null, false, false, false); 2095 Module m2 = mgr.create(new File (jars, "uses-api-friend.jar"), null, false, false, false); 2096 Module m3 = mgr.create(new File (jars, "uses-and-exports-api.jar"), null, false, false, false); 2097 Module m4 = mgr.create(new File (jars, "uses-api-directly.jar"), null, false, false, false); 2098 Module m5 = mgr.create(new File (jars, "uses-api-impl-dep-for-friends.jar"), null, false, false, false); 2099 assertEquals("api-mod-export-api.jar had no problems", Collections.EMPTY_SET, m1.getProblems()); 2100 assertEquals("uses-api-friend.jar had no problems", Collections.EMPTY_SET, m2.getProblems()); 2101 assertEquals("uses-and-exports-api.jar had no problems", Collections.EMPTY_SET, m3.getProblems()); 2102 assertEquals("uses-api-directly.jar had no problems", Collections.EMPTY_SET, m4.getProblems()); 2103 assertEquals("uses-api-impl-dep-for-friends.jar had no problems", Collections.EMPTY_SET, m5.getProblems()); 2104 mgr.enable(new HashSet <Module>(Arrays.asList(m1, m2, m3, m4, m5))); 2105 m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2106 try { 2107 m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2108 fail ("Even friends modules cannot access implementation classes"); 2109 } catch (NoClassDefFoundError ex) { 2110 } 2112 2113 try { 2114 m4.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2115 fail ("m4 is not friend and should not be allowed to load the class"); 2116 } catch (NoClassDefFoundError ex) { 2117 } 2119 try { 2120 m4.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2121 fail ("m4 is not friend and should not be allowed to load the implementation either"); 2122 } catch (NoClassDefFoundError ex) { 2123 } 2125 try { 2126 m5.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance(); 2127 } catch (NoClassDefFoundError e) { 2128 fail("m5 has an implementation dependency and has not been allowed to load the public class"); 2129 } 2130 try { 2131 m5.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance(); 2132 } catch (NoClassDefFoundError e) { 2133 fail("m5 has an implementation dependency and has not been allowed to load the imlpementation class"); 2134 } 2135 2136 mgr.disable(new HashSet <Module>(Arrays.asList(m1, m2, m3, m4, m5))); 2137 mgr.delete(m5); 2138 mgr.delete(m4); 2139 mgr.delete(m3); 2140 mgr.delete(m2); 2141 mgr.delete(m1); 2142 } finally { 2143 mgr.mutexPrivileged().exitWriteAccess(); 2144 } 2145 } 2146 2147 public void testModuleInterdependencies() throws Exception { 2148 FakeModuleInstaller installer = new FakeModuleInstaller(); 2149 FakeEvents ev = new FakeEvents(); 2150 ModuleManager mgr = new ModuleManager(installer, ev); 2151 mgr.mutexPrivileged().enterWriteAccess(); 2152 try { 2153 Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 2154 Module m2 = mgr.create(new File (jars, "depends-on-simple-module.jar"), null, false, false, false); 2155 Module m3 = mgr.create(new File (jars, "dep-on-dep-on-simple.jar"), null, false, false, false); 2156 Set <Module> m1m2 = new HashSet <Module>(Arrays.asList(m1, m2)); 2157 Set <Module> m2m3 = new HashSet <Module>(Arrays.asList(m2, m3)); 2158 assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m1, false, false)); 2159 assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m1, false, true)); 2160 assertEquals(Collections.singleton(m2), mgr.getModuleInterdependencies(m1, true, false)); 2161 assertEquals(m2m3, mgr.getModuleInterdependencies(m1, true, true)); 2162 assertEquals(Collections.singleton(m1), mgr.getModuleInterdependencies(m2, false, false)); 2163 assertEquals(Collections.singleton(m1), mgr.getModuleInterdependencies(m2, false, true)); 2164 assertEquals(Collections.singleton(m3), mgr.getModuleInterdependencies(m2, true, false)); 2165 assertEquals(Collections.singleton(m3), mgr.getModuleInterdependencies(m2, true, true)); 2166 assertEquals(Collections.singleton(m2), mgr.getModuleInterdependencies(m3, false, false)); 2167 assertEquals(m1m2, mgr.getModuleInterdependencies(m3, false, true)); 2168 assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m3, true, false)); 2169 assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m3, true, true)); 2170 m1 = mgr.create(new File (jars, "prov-foo.jar"), null, false, false, false); 2171 m2 = mgr.create(new File (jars, "prov-foo-bar.jar"), null, false, false, false); 2172 m3 = mgr.create(new File (jars, "req-foo.jar"), null, false, false, false); 2173 Module m4 = mgr.create(new File (jars, "prov-baz.jar"), null, false, false, false); 2174 Module m5 = mgr.create(new File (jars, "req-foo-baz.jar"), null, false, false, false); 2175 m1m2 = new HashSet <Module>(Arrays.asList(m1, m2)); 2176 assertEquals(m1m2, mgr.getModuleInterdependencies(m3, false, true)); 2177 Set <Module> m1m2m4 = new HashSet <Module>(Arrays.asList(m1, m2, m4)); 2178 assertEquals(m1m2m4, mgr.getModuleInterdependencies(m5, false, true)); 2179 Set <Module> m3m5 = new HashSet <Module>(Arrays.asList(m3, m5)); 2180 assertEquals(m3m5, mgr.getModuleInterdependencies(m1, true, true)); 2181 } finally { 2183 mgr.mutexPrivileged().exitWriteAccess(); 2184 } 2185 } 2186 2187 public void testModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue() throws Exception { 2188 doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (1); 2189 } 2190 public void testGlobalClassLoaderWasNotReadyWhenTheChangeWasFiredIssue() throws Exception { 2191 doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (2); 2192 } 2193 public void testModuleManagerClassLoaderWasNotReadyWhenTheChangeWasFiredIssue() throws Exception { 2194 doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (3); 2195 } 2196 2197 private void doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (final int typeOfClassLoader) throws Exception { 2198 FakeModuleInstaller installer = new FakeModuleInstaller(); 2199 FakeEvents ev = new FakeEvents(); 2200 final ModuleManager mgr = new ModuleManager(installer, ev); 2201 mgr.mutexPrivileged().enterWriteAccess(); 2202 try { 2203 final Module m1 = mgr.create(new File (jars, "simple-module.jar"), null, false, false, false); 2204 2205 class L implements java.beans.PropertyChangeListener { 2206 ClassLoader l; 2207 IllegalStateException ex; 2208 2209 public void propertyChange (java.beans.PropertyChangeEvent event) { 2210 if (m1.PROP_ENABLED.equals (event.getPropertyName ())) { 2211 try { 2212 this.l = get (); 2213 } catch (IllegalStateException ex) { 2214 this.ex = ex; 2215 } 2216 } 2217 } 2218 2219 public ClassLoader get () { 2220 switch (typeOfClassLoader) { 2221 case 1: return m1.getClassLoader (); 2222 case 2: return Thread.currentThread ().getContextClassLoader (); 2223 case 3: return mgr.getClassLoader (); 2224 } 2225 fail ("Wrong type: " + typeOfClassLoader); 2226 return null; 2227 } 2228 } 2229 L l = new L (); 2230 m1.addPropertyChangeListener (l); 2231 2232 mgr.enable (m1); 2233 2234 assertTrue ("Successfully enabled", m1.isEnabled ()); 2235 assertEquals ("Classloader at the time of PROP_ENABLED is the same as now", l.get (), l.l); 2236 assertNull ("No exception thrown", l.ex); 2237 m1.removePropertyChangeListener (l); 2239 2240 mgr.disable (m1); 2241 } finally { 2242 mgr.mutexPrivileged().exitWriteAccess(); 2243 } 2244 } 2245 2246 2247 public void testProblemsStillCorrectWithHardAndSoftMixture() throws Exception { 2248 File m1j = new File (getWorkDir(), "m1.jar"); 2249 createJar(m1j, Collections.<String ,String >emptyMap(), Collections.singletonMap("OpenIDE-Module", "m1")); 2250 File m2j = new File (getWorkDir(), "m2.jar"); 2251 Map <String ,String > mani = new HashMap <String ,String >(); 2252 mani.put("OpenIDE-Module", "m2"); 2253 mani.put("OpenIDE-Module-Module-Dependencies", "m1"); 2254 mani.put("OpenIDE-Module-Java-Dependencies", "Java > 2046"); 2255 createJar(m2j, Collections.<String ,String >emptyMap(), mani); 2256 FakeModuleInstaller installer = new FakeModuleInstaller(); 2257 FakeEvents ev = new FakeEvents(); 2258 ModuleManager mgr = new ModuleManager(installer, ev); 2259 mgr.mutexPrivileged().enterWriteAccess(); 2260 try { 2261 Module m2 = mgr.create(m2j, null, false, false, false); 2262 assertEquals("initially m2 has two problems: Java and m1", 2, m2.getProblems().size()); 2263 Module m1 = mgr.create(m1j, null, false, false, false); 2264 assertEquals("m1 has no problems", Collections.emptySet(), m1.getProblems()); 2265 assertEquals("now m2 should have just one problem: Java", 1, m2.getProblems().size()); 2266 Dependency d = (Dependency) m2.getProblems().iterator().next(); 2267 assertEquals(Dependency.TYPE_JAVA, d.getType()); 2268 } finally { 2269 mgr.mutexPrivileged().exitWriteAccess(); 2270 } 2271 } 2272 2273 private File copyJar(File file, String manifest) throws IOException { 2274 File ret = File.createTempFile(file.getName(), "2ndcopy", file.getParentFile()); 2275 JarFile jar = new JarFile (file); 2276 JarOutputStream os = new JarOutputStream (new FileOutputStream (ret), new Manifest ( 2277 new ByteArrayInputStream (manifest.getBytes()) 2278 )); 2279 Enumeration <JarEntry > en = jar.entries(); 2280 while (en.hasMoreElements()) { 2281 JarEntry elem = en.nextElement(); 2282 if (elem.getName().equals("META-INF/MANIFEST.MF")) { 2283 continue; 2284 } 2285 os.putNextEntry(elem); 2286 InputStream is = jar.getInputStream(elem); 2287 FileUtil.copy(is, os); 2288 is.close(); 2289 } 2290 os.close(); 2291 return ret; 2292 } 2293 2294 private static Module createModule(ModuleManager mgr, String manifest) throws Exception { 2295 return mgr.createFixed(new Manifest (new ByteArrayInputStream (manifest.getBytes())), null, ModuleManagerTest.class.getClassLoader()); 2296 } 2297 2298} 2299 | Popular Tags |