001 package org.picocontainer.defaults.issues;
002
003 import junit.framework.TestCase;
004
005 import java.util.List;
006 import java.util.ArrayList;
007
008 import org.picocontainer.PicoContainer;
009 import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory;
010 import org.picocontainer.defaults.DefaultPicoContainer;
011 import org.picocontainer.defaults.SynchronizedComponentAdapterFactory;
012
013 public class Issue0199TestCase extends TestCase {
014
015 public static class A {
016 public A(C c) {}
017 }
018
019 public static class B {
020 public B(C c) {}
021 }
022
023 public static class C {}
024
025 class Runner extends Thread {
026 private PicoContainer container;
027 private Object componentKey;
028 private Throwable throwable;
029 private boolean finished;
030
031 Runner(String name, PicoContainer container, Object componentKey) {
032 super(name);
033 this.container = container;
034 this.componentKey = componentKey;
035 }
036
037 public void run() {
038 try {
039 report("Started instantiating " + componentKey.toString());
040 container.getComponentInstance(componentKey);
041 report("Finished instantiating " + componentKey.toString());
042 finished = true;
043 } catch (Throwable t) {
044 this.throwable = t;
045 }
046 }
047
048 private void report(String messsage) {
049 System.out.println(getName() + ": " + messsage);
050 }
051
052 public boolean isFinished() {
053 return finished;
054 }
055
056 public Throwable getThrowable() {
057 return throwable;
058 }
059 }
060
061 public void testPicoContainerCausesDeadlock() throws InterruptedException {
062 DefaultPicoContainer container = createContainer();
063 container.registerComponentImplementation("A", A.class);
064 container.registerComponentImplementation("B", B.class);
065 container.registerComponentImplementation("C", C.class);
066
067 final int THREAD_COUNT = 2;
068 List runnerList = new ArrayList(THREAD_COUNT);
069
070 for (int i = 0; i < THREAD_COUNT; ++i) {
071 Runner runner = new Runner("Runner " + i, container, (i % 2 == 0) ? "A" : "B");
072 runnerList.add(runner);
073 runner.start();
074 }
075
076 final long WAIT_TIME = 1000;
077
078 for (int i = 0; i < THREAD_COUNT; ++i) {
079 Runner runner = (Runner) runnerList.get(i);
080 runner.join(WAIT_TIME);
081 assertTrue("Deadlock occurred", runner.isFinished());
082 }
083 }
084
085 private DefaultPicoContainer createContainer() {
086 return new DefaultPicoContainer(
087 new SynchronizedComponentAdapterFactory(
088 new ConstructorInjectionComponentAdapterFactory()));
089 }
090 }