1 package org.codehaus.plexus.test;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.File;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.UUID;
26 import java.util.concurrent.CopyOnWriteArrayList;
27 import java.util.concurrent.CountDownLatch;
28 import java.util.concurrent.atomic.AtomicBoolean;
29
30 import junit.framework.TestCase;
31 import org.codehaus.plexus.ContainerConfiguration;
32 import org.codehaus.plexus.DefaultContainerConfiguration;
33 import org.codehaus.plexus.DefaultPlexusContainer;
34 import org.codehaus.plexus.classworlds.realm.ClassRealm;
35 import org.codehaus.plexus.component.discovery.DiscoveredComponent;
36 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
37 import org.codehaus.plexus.lifecycle.BasicLifecycleHandler;
38 import org.codehaus.plexus.lifecycle.LifecycleHandler;
39 import org.codehaus.plexus.test.lifecycle.phase.EenyPhase;
40 import org.codehaus.plexus.test.lifecycle.phase.MeenyPhase;
41 import org.codehaus.plexus.test.lifecycle.phase.MinyPhase;
42 import org.codehaus.plexus.test.lifecycle.phase.MoPhase;
43 import org.codehaus.plexus.test.list.Pipeline;
44 import org.codehaus.plexus.test.list.Valve;
45 import org.codehaus.plexus.test.list.ValveFour;
46 import org.codehaus.plexus.test.list.ValveOne;
47 import org.codehaus.plexus.test.list.ValveThree;
48 import org.codehaus.plexus.test.list.ValveTwo;
49 import org.codehaus.plexus.test.map.Activity;
50 import org.codehaus.plexus.test.map.ActivityManager;
51
52 public class PlexusContainerTest extends TestCase {
53 private String basedir;
54
55 private ClassLoader classLoader;
56
57 private String configuration;
58
59 private DefaultPlexusContainer container;
60
61 public PlexusContainerTest(String name) {
62 super(name);
63 }
64
65 public void setUp() throws Exception {
66 basedir = System.getProperty("basedir");
67
68 classLoader = getClass().getClassLoader();
69
70 configuration = "/" + getClass().getName().replace('.', '/') + ".xml";
71
72 assertNotNull(classLoader);
73
74
75
76
77
78 Map<Object, Object> context = new HashMap<Object, Object>();
79
80 context.put("basedir", basedir);
81
82 context.put("plexus.home", basedir + "/target/plexus-home");
83
84 LifecycleHandler arbitrary = new BasicLifecycleHandler("arbitrary");
85 arbitrary.addBeginSegment(new EenyPhase());
86 arbitrary.addBeginSegment(new MeenyPhase());
87 arbitrary.addBeginSegment(new MinyPhase());
88 arbitrary.addBeginSegment(new MoPhase());
89
90 ContainerConfiguration containerConfiguration = new DefaultContainerConfiguration()
91 .setName("test")
92 .setContext(context)
93 .setContainerConfiguration(configuration)
94 .addLifecycleHandler(arbitrary);
95
96 container = new DefaultPlexusContainer(containerConfiguration);
97 }
98
99 public void tearDown() throws Exception {
100 container.dispose();
101
102 container = null;
103 }
104
105 public void testDefaultPlexusContainerSetup() throws Exception {
106 assertEquals("bar", System.getProperty("foo"));
107 }
108
109
110
111
112
113
114
115 public void testNativeLifecyclePassage() throws Exception {
116 DefaultServiceB serviceB = (DefaultServiceB) container.lookup(ServiceB.class);
117
118
119 assertNotNull(serviceB);
120
121
122 assertEquals(true, serviceB.enableLogging);
123
124 assertEquals(true, serviceB.contextualize);
125
126 assertEquals(true, serviceB.initialize);
127
128 assertEquals(true, serviceB.start);
129
130 assertEquals(false, serviceB.stop);
131
132 container.release(serviceB);
133
134 assertEquals(true, serviceB.stop);
135 }
136
137 public void testConfigurableLifecyclePassage() throws Exception {
138 DefaultServiceE serviceE = (DefaultServiceE) container.lookup(ServiceE.class);
139
140
141 assertNotNull(serviceE);
142
143
144 assertEquals(true, serviceE.enableLogging);
145
146 assertEquals(true, serviceE.contextualize);
147
148 assertEquals(true, serviceE.initialize);
149
150 assertEquals(true, serviceE.start);
151
152 assertEquals(false, serviceE.stop);
153
154 container.release(serviceE);
155
156 assertEquals(true, serviceE.stop);
157 }
158
159
160
161
162
163 public void testSingleComponentLookupWithRoleHint() throws Exception {
164
165 DefaultServiceC serviceC1 = (DefaultServiceC) container.lookup(ServiceC.class, "first-instance");
166
167
168 assertNotNull(serviceC1);
169
170 assertTrue(serviceC1.started);
171
172 assertFalse(serviceC1.stopped);
173
174
175 DefaultServiceC serviceC2 = (DefaultServiceC) container.lookup(ServiceC.class, "first-instance");
176
177
178 assertNotNull(serviceC2);
179
180 assertTrue(serviceC2.started);
181
182 assertFalse(serviceC2.stopped);
183
184
185 assertSame(serviceC1, serviceC2);
186
187 container.release(serviceC1);
188
189
190 assertTrue(serviceC2.started);
191
192 assertTrue(serviceC2.stopped);
193
194 container.release(serviceC2);
195
196
197 assertTrue(serviceC2.started);
198
199 assertTrue(serviceC2.stopped);
200 }
201
202
203
204
205 public void testMultipleSingletonComponentInstances() throws Exception {
206
207 DefaultServiceC serviceC1 = (DefaultServiceC) container.lookup(ServiceC.class, "first-instance");
208
209
210 assertNotNull(serviceC1);
211
212 assertTrue(serviceC1.started);
213
214 assertFalse(serviceC1.stopped);
215
216
217
218 DefaultServiceC serviceC2 = (DefaultServiceC) container.lookup(ServiceC.class, "second-instance");
219
220
221 assertNotNull(serviceC2);
222
223 assertTrue(serviceC2.started);
224
225 assertFalse(serviceC2.stopped);
226
227
228 assertNotSame(serviceC1, serviceC2);
229
230 container.release(serviceC1);
231
232
233
234 assertTrue(serviceC1.started);
235
236 assertTrue(serviceC1.stopped);
237
238 assertTrue(serviceC2.started);
239
240 assertFalse(serviceC2.stopped);
241
242 container.release(serviceC2);
243
244
245 assertTrue(serviceC2.started);
246
247 assertTrue(serviceC2.stopped);
248 }
249
250
251
252
253
254 public void testArbitraryLifecyclePassageUsingFourArbitraryPhases() throws Exception {
255
256 DefaultServiceH serviceH = (DefaultServiceH) container.lookup(ServiceH.class);
257
258
259 assertNotNull(serviceH);
260
261
262 assertEquals(true, serviceH.eeny);
263
264 assertEquals(true, serviceH.meeny);
265
266 assertEquals(true, serviceH.miny);
267
268 assertEquals(true, serviceH.mo);
269
270 container.release(serviceH);
271 }
272
273 public void testLookupAll() throws Exception {
274 Map<String, ServiceC> components = container.lookupMap(ServiceC.class);
275
276 assertNotNull(components);
277
278 assertEquals(2, components.size());
279
280 ServiceC component = components.get("first-instance");
281
282 assertNotNull(component);
283
284 component = components.get("second-instance");
285
286 assertNotNull(component);
287
288 container.releaseAll(components);
289 }
290
291 public void testAutomatedComponentConfigurationUsingXStreamPoweredComponentConfigurator() throws Exception {
292 Component component = container.lookup(Component.class);
293
294 assertNotNull(component);
295
296 assertNotNull(component.getActivity());
297
298 assertEquals("localhost", component.getHost());
299
300 assertEquals(10000, component.getPort());
301 }
302
303 public void testAutomatedComponentComposition() throws Exception {
304 ComponentA componentA = container.lookup(ComponentA.class);
305
306 assertNotNull(componentA);
307
308 assertEquals("localhost", componentA.getHost());
309
310 assertEquals(10000, componentA.getPort());
311
312 ComponentB componentB = componentA.getComponentB();
313
314 assertNotNull(componentB);
315
316 ComponentC componentC = componentA.getComponentC();
317
318 assertNotNull(componentC);
319
320 ComponentD componentD = componentC.getComponentD();
321
322 assertNotNull(componentD);
323
324 assertEquals("jason", componentD.getName());
325 }
326
327 public void testComponentCompositionWhereTargetFieldIsAMap() throws Exception {
328 ActivityManager am = container.lookup(ActivityManager.class);
329
330 Activity one = am.getActivity("one");
331
332 assertNotNull(one);
333
334
335 assertSame(one, am.getActivity("one"));
336
337 assertFalse(one.getState());
338
339 am.execute("one");
340
341 assertTrue(one.getState());
342
343 Activity two = am.getActivity("two");
344
345 assertNotNull(two);
346
347 assertFalse(two.getState());
348
349 am.execute("two");
350
351 assertTrue(two.getState());
352 }
353
354 public void testComponentCompositionWhereTargetFieldIsAPartialMap() throws Exception {
355 ActivityManager am = container.lookup(ActivityManager.class, "slim");
356
357 assertEquals(1, am.getActivityCount());
358
359 Activity one = am.getActivity("one");
360
361 assertNotNull(one);
362
363 assertFalse(one.getState());
364
365 am.execute("one");
366
367 assertTrue(one.getState());
368 }
369
370 public void testComponentCompositionWhereTargetFieldIsAList() throws Exception {
371 Pipeline pipeline = container.lookup(Pipeline.class);
372
373 List valves = pipeline.getValves();
374
375 for (Object valve : valves) {
376
377 assertSame(valve, valve);
378 }
379
380 assertFalse(((Valve) valves.get(0)).getState());
381
382 assertFalse(((Valve) valves.get(1)).getState());
383
384 pipeline.execute();
385
386 assertTrue(((Valve) valves.get(0)).getState());
387
388 assertTrue(((Valve) valves.get(1)).getState());
389 }
390
391 public void testComponentCompositionWhereTargetFieldIsAPartialList() throws Exception {
392 Pipeline pipeline = container.lookup(Pipeline.class, "slim");
393
394 List valves = pipeline.getValves();
395
396 assertEquals(valves.size(), 1);
397
398 assertFalse(((Valve) valves.get(0)).getState());
399
400 pipeline.execute();
401
402 assertTrue(((Valve) valves.get(0)).getState());
403 }
404
405 public void testComponentCompositionWhereTargetFieldAMapThatMustRetainTheOrderOfComponentsGivenASetOfRoleHints()
406 throws Exception {
407 Pipeline pipeline = container.lookup(Pipeline.class, "chubby");
408
409 Map valveMap = pipeline.getValveMap();
410
411 List valves = new ArrayList(valveMap.values());
412
413 assertEquals("Expecting three valves.", 4, valves.size());
414
415 assertTrue("Expecting valve one.", valves.get(0) instanceof ValveOne);
416
417 assertTrue("Expecting valve two.", valves.get(1) instanceof ValveTwo);
418
419 assertTrue("Expecting valve three.", valves.get(2) instanceof ValveThree);
420
421 assertTrue("Expecting valve four.", valves.get(3) instanceof ValveFour);
422 }
423
424 public void testLookupOfComponentThatShouldBeDiscovered() throws Exception {
425 DiscoveredComponent discoveredComponent = container.lookup(DiscoveredComponent.class);
426
427 assertNotNull(discoveredComponent);
428 }
429
430 public void testStartableComponentSnake() throws Exception {
431 StartableComponent ca = container.lookup(StartableComponent.class, "A-snake");
432
433 assertNotNull(ca);
434
435 ca.assertStartOrderCorrect();
436
437 container.dispose();
438
439 ca.assertStopOrderCorrect();
440 }
441
442 public void testStartableComponentTree() throws Exception {
443 StartableComponent ca = container.lookup(StartableComponent.class, "A-tree");
444
445 assertNotNull(ca);
446
447 ca.assertStartOrderCorrect();
448
449 container.dispose();
450
451 ca.assertStopOrderCorrect();
452 }
453
454 public void testLookupCircularity() throws Exception {
455 try {
456 container.lookup(CircularComponent.class, "A");
457 fail("Expected ComponentLookupException due to circularity");
458 } catch (ComponentLookupException e) {
459
460 }
461 }
462
463 public void testAddComponent() throws Exception {
464 LiveComponent live = new LiveComponent();
465
466 container.addComponent(live, LiveComponent.class.getName());
467
468 LiveComponent c = container.lookup(LiveComponent.class);
469
470 assertSame(live, c);
471 }
472
473 public void testComponentOverride() throws Exception {
474 assertNotNull(container.lookup(Component.class));
475
476 Component live = new Component() {
477 public Activity getActivity() {
478 return null;
479 }
480
481 public String getHost() {
482 return null;
483 }
484
485 public int getPort() {
486 return 0;
487 }
488 };
489
490 container.addComponent(live, Component.class, null);
491
492 assertSame(live, container.lookup(Component.class));
493 }
494
495 public void testUpdateOfActiveComponentCollectionUponChangeOfThreadContextClassLoader() throws Exception {
496 ComponentManager manager = container.lookup(ComponentManager.class);
497
498 Map<String, ?> map = manager.getMap();
499 assertNotNull(map);
500 assertEquals(0, map.size());
501
502 List<?> list = manager.getList();
503 assertNotNull(list);
504 assertEquals(0, list.size());
505
506
507
508
509
510
511
512 ClassRealm realmA = container.createChildRealm("realm-a");
513 realmA.addURL(new File("src/test/test-components/component-a-1.0-SNAPSHOT.jar")
514 .toURI()
515 .toURL());
516 container.discoverComponents(realmA);
517
518 ClassRealm realmB = container.createChildRealm("realm-b");
519 realmB.addURL(new File("src/test/test-components/component-a-2.0-SNAPSHOT.jar")
520 .toURI()
521 .toURL());
522 container.discoverComponents(realmB);
523
524 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
525
526 try {
527 Thread.currentThread().setContextClassLoader(realmA);
528
529 map = manager.getMap();
530 assertNotNull(map);
531 assertEquals(1, map.size());
532 assertSame(realmA, map.values().iterator().next().getClass().getClassLoader());
533
534 list = manager.getList();
535 assertNotNull(list);
536 assertEquals(1, list.size());
537 assertSame(realmA, list.iterator().next().getClass().getClassLoader());
538
539 Thread.currentThread().setContextClassLoader(realmB);
540
541 map = manager.getMap();
542 assertNotNull(map);
543 assertEquals(1, map.size());
544 assertSame(realmB, map.values().iterator().next().getClass().getClassLoader());
545
546 list = manager.getList();
547 assertNotNull(list);
548 assertEquals(1, list.size());
549 assertSame(realmB, list.iterator().next().getClass().getClassLoader());
550 } finally {
551 Thread.currentThread().setContextClassLoader(oldClassLoader);
552 }
553 }
554
555 public void testUpdateOfActiveComponentCollectionUponChangeOfThreadContextClassLoaderFromParentToChildRealm()
556 throws Exception {
557 ComponentManager manager = container.lookup(ComponentManager.class);
558
559 Map<String, ?> map = manager.getMap();
560 assertNotNull(map);
561 assertEquals(0, map.size());
562
563 List<?> list = manager.getList();
564 assertNotNull(list);
565 assertEquals(0, list.size());
566
567
568
569
570
571
572
573
574
575 ClassRealm realmA = container.createChildRealm("realm-a");
576 realmA.addURL(new File("src/test/test-components/component-a-1.0-SNAPSHOT.jar")
577 .toURI()
578 .toURL());
579 container.discoverComponents(realmA);
580
581 ClassRealm realmB = realmA.createChildRealm("realm-b");
582 realmB.importFrom(realmA, "org.codehaus.plexus.components.A");
583 realmB.importFromParent("nothing");
584 realmB.addURL(new File("src/test/test-components/component-a-2.0-SNAPSHOT.jar")
585 .toURI()
586 .toURL());
587 container.discoverComponents(realmB);
588
589 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
590
591 try {
592 Thread.currentThread().setContextClassLoader(realmA);
593
594 map = manager.getMap();
595 assertNotNull(map);
596 assertEquals(1, map.size());
597 assertSame(realmA, map.values().iterator().next().getClass().getClassLoader());
598
599 list = manager.getList();
600 assertNotNull(list);
601 assertEquals(1, list.size());
602 assertSame(realmA, list.iterator().next().getClass().getClassLoader());
603
604 Thread.currentThread().setContextClassLoader(realmB);
605
606 map = manager.getMap();
607 assertNotNull(map);
608 assertEquals(1, map.size());
609 assertSame(realmB, map.values().iterator().next().getClass().getClassLoader());
610
611 list = manager.getList();
612 assertNotNull(list);
613 assertEquals(1, list.size());
614 assertSame(realmB, list.iterator().next().getClass().getClassLoader());
615 } finally {
616 Thread.currentThread().setContextClassLoader(oldClassLoader);
617 }
618 }
619
620 public void testComponentLookupFromParentRealmOfImportedRealms() throws Exception {
621 ComponentManager manager = container.lookup(ComponentManager.class);
622
623 Map<String, ?> map = manager.getMap();
624 assertNotNull(map);
625 assertEquals(0, map.size());
626
627 List<?> list = manager.getList();
628 assertNotNull(list);
629 assertEquals(0, list.size());
630
631 URL componentUrl = new File("src/test/test-components/component-a-1.0-SNAPSHOT.jar")
632 .toURI()
633 .toURL();
634
635 ClassRealm realmP = container.createChildRealm("parent-of-imported-realm");
636 realmP.addURL(componentUrl);
637 container.discoverComponents(realmP);
638
639 ClassRealm realmI = realmP.createChildRealm("imported-realm");
640
641 ClassRealm realmL = container.createChildRealm("lookup-realm");
642 realmL.importFrom(realmI, "org.something");
643
644 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
645
646 try {
647 Thread.currentThread().setContextClassLoader(realmL);
648
649 map = manager.getMap();
650 assertNotNull(map);
651 assertEquals(1, map.size());
652 assertSame(realmP, map.values().iterator().next().getClass().getClassLoader());
653
654 list = manager.getList();
655 assertNotNull(list);
656 assertEquals(1, list.size());
657 assertSame(realmP, list.iterator().next().getClass().getClassLoader());
658 } finally {
659 Thread.currentThread().setContextClassLoader(oldClassLoader);
660 }
661 }
662
663 public void testOptionalComponentRequirement() throws Exception {
664 DefaultComponentWithOptionalRequirement ca =
665 (DefaultComponentWithOptionalRequirement) container.lookup(Component.class, "with-optional");
666
667 assertNotNull(ca);
668
669 assertNotNull(ca.getActivity());
670
671 assertNull(ca.optionalComponent);
672 }
673
674 public void testLookupOfComponentThatHasARequirementWithoutRoleHintAndTheOneAndOnlyImplHasNoDefaultHint()
675 throws Exception {
676 DefaultThingUser component = (DefaultThingUser) container.lookup(ThingUser.class);
677
678 assertNotNull(component.thing);
679 }
680
681 public void testSingleLookupWithAndWithoutRoleHint() throws Exception {
682 ComponentWithRoleDefault withRoleHint = container.lookup(ComponentWithRoleDefault.class, "default");
683
684 ComponentWithRoleDefault withoutRoleHint = container.lookup(ComponentWithRoleDefault.class);
685
686 assertSame(withRoleHint, withoutRoleHint);
687 }
688
689 public void testLookupUponChangeOfThreadContextClassLoaderFromParentToChildRealm() throws Exception {
690
691
692
693
694
695
696
697
698 ClassRealm realmA = container.createChildRealm("realm-a");
699 realmA.addURL(new File("src/test/test-components/component-a-1.0-SNAPSHOT.jar")
700 .toURI()
701 .toURL());
702 container.discoverComponents(realmA);
703
704 ClassRealm realmB = realmA.createChildRealm("realm-b");
705 realmB.importFrom(realmA, "org.codehaus.plexus.components.A");
706 realmB.importFromParent("nothing");
707 realmB.addURL(new File("src/test/test-components/component-a-2.0-SNAPSHOT.jar")
708 .toURI()
709 .toURL());
710 container.discoverComponents(realmB);
711
712 Class<?> role = realmA.loadClass("org.codehaus.plexus.components.A");
713
714 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
715
716 try {
717 Thread.currentThread().setContextClassLoader(realmA);
718
719 Object comp1 = container.lookup(role, "default");
720
721 Thread.currentThread().setContextClassLoader(realmB);
722
723 Object comp2 = container.lookup(role, "default");
724
725 assertNotNull(comp1);
726 assertNotNull(comp2);
727 assertNotSame(comp1, comp2);
728 assertSame(realmA, comp1.getClass().getClassLoader());
729 assertSame(realmB, comp2.getClass().getClassLoader());
730 } finally {
731 Thread.currentThread().setContextClassLoader(oldClassLoader);
732 }
733 }
734
735 public void testSafeConcurrentAccessToActiveComponentCollection() throws Exception {
736 ComponentManager manager = container.lookup(ComponentManager.class);
737
738 final Map<String, ?> map = manager.getMap();
739 assertNotNull(map);
740 assertEquals(0, map.size());
741
742 final List<?> list = manager.getList();
743 assertNotNull(list);
744 assertEquals(0, list.size());
745
746 final AtomicBoolean go = new AtomicBoolean(false);
747
748 final List<Exception> exceptions = new CopyOnWriteArrayList<Exception>();
749 Thread[] threads = new Thread[64];
750 final CountDownLatch latch = new CountDownLatch(threads.length);
751 for (int i = 0; i < threads.length; i++) {
752 threads[i] = new Thread() {
753 @Override
754 public void run() {
755 try {
756 ClassRealm realm = container.createChildRealm(
757 "realm-" + UUID.randomUUID().toString());
758 realm.addURL(new File("src/test/test-components/component-a-1.0-SNAPSHOT.jar")
759 .toURI()
760 .toURL());
761 container.discoverComponents(realm);
762 Thread.currentThread().setContextClassLoader(realm);
763
764 while (!go.get()) {
765
766 }
767
768 for (int j = 0; j < 1000; j++) {
769
770 for (Object value : map.values()) {
771 value.toString();
772 }
773 for (Object value : list) {
774 value.toString();
775 }
776 }
777 } catch (Exception e) {
778 e.printStackTrace();
779 exceptions.add(e);
780 } finally {
781 latch.countDown();
782 }
783 }
784 };
785 threads[i].start();
786 }
787 go.set(true);
788 latch.await();
789
790 assertTrue(exceptions.toString(), exceptions.isEmpty());
791 }
792 }