package org.jboss.seam.test.integration;
import static org.jboss.seam.ScopeType.APPLICATION;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.core.Expressions;
import org.jboss.seam.mock.JUnitSeamTest;
import org.junit.Test;
import org.junit.After;
// JBSEAM-4669
public class ConcurrentFactoryTest
extends JUnitSeamTest
{
private volatile boolean exceptionOccured = false;
static AtomicInteger testSequence = new AtomicInteger(0);
private void concurrentFactoryCallTest() throws Exception {
new ComponentTest() {
@Override
protected void testComponents() throws Exception {
int myTestSequence;
myTestSequence = testSequence.getAndIncrement();
if (myTestSequence == 0) {
assert "TestString".equals(getValue("#{concurrentFactoryTest.LockHoldingComponent.string}"));
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
assert "TestString".equals(getValue("#{concurrentFactoryTest.dependentString}"));
}
System.out.println(myTestSequence);
}
}.run();
}
private class ConcurrentFactoryCallTestThread extends Thread
{
public void run() {
try
{
ConcurrentFactoryTest.this.concurrentFactoryCallTest();
}
catch (Throwable e)
{
e.printStackTrace();
ConcurrentFactoryTest.this.exceptionOccured = true;
}
};
}
@Test(timeout=10000)
public void concurrentFactoryCall()
throws Exception
{
Thread thread1 = new ConcurrentFactoryCallTestThread();
Thread thread2 = new ConcurrentFactoryCallTestThread();
thread1.start();
thread2.start();
thread1.join();
thread2.join();
assert !exceptionOccured;
}
@Name("concurrentFactoryTest.LockHoldingComponent")
@Scope(APPLICATION)
static public class LockHoldingComponent implements Serializable {
@In(value = "concurrentFactoryTest.slowlyCreatedComponent", create = true) SlowlyCreatedComponent slowlyCreatedComponent;
public String getString() {
return (String) Expressions.instance().createValueExpression("#{concurrentFactoryTest.plainFactoryGeneratedString}").getValue();
}
}
@Name("concurrentFactoryTest.slowlyCreatedComponent")
static public class SlowlyCreatedComponent {
@Create
public void slowlyCreate() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Name("concurrentFactoryTest.dependentFactory")
static public class DependentFactory {
@Factory(value = "concurrentFactoryTest.dependentString", scope = APPLICATION, autoCreate = true)
public String createString() {
return (String) Expressions.instance().createValueExpression("#{concurrentFactoryTest.LockHoldingComponent.string}").getValue();
}
}
@Name("concurrentFactoryTest.plainFactory")
static public class PlainFactory {
@Factory(value = "concurrentFactoryTest.plainFactoryGeneratedString", scope = APPLICATION, autoCreate = true)
public String createPlainString() {
return "TestString";
}
}
@After
@Override
public void end()
{
// don't attempt to endSession, as it will block in the deadlocked org.jboss.seam.Component.getInstanceFromFactory lock
}
}