[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[aspectj-users] Creation of parameterized ReferenceType not thread safe
|
Hi,
I am currently struggling with an IndexOutOfBoundsException deep in aspectj.
at java.util.ArrayList.add(ArrayList.java:352)
at org.aspectj.weaver.ReferenceType.addDependentType(ReferenceType.java:115)
at org.aspectj.weaver.ReferenceType.<init>(ReferenceType.java:95)
at org.aspectj.weaver.TypeFactory.createParameterizedType(TypeFactory.java:43)
After taking a deeper look into the code, I found out that the usage of TypeFactory.createParameterizedType() and in particular the instantiation of ReferenceType (line 43 of TypeFactory) is not thread safe. In a short program (see below) I could reproduce this issue, when passing the same instance of ResolvedType.
Is this a bug, or should this not happen when aspectj is used in a proper way?
Regards
Thorsten
--- sample program start ---
import java.util.concurrent.CountDownLatch;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.TypeFactory;
import org.aspectj.weaver.World;
import org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate;
import org.aspectj.weaver.reflect.ReflectionWorld;
public class Aspectj {
public static void main(String[] args) {
new Aspectj();
}
static World inAWorld = new ReflectionWorld(Aspectj.class.getClassLoader());
static ReferenceType aBaseType;
static {
aBaseType = new ReferenceType("test", inAWorld);
Java15ReflectionBasedReferenceTypeDelegate delegate = new Java15ReflectionBasedReferenceTypeDelegate();
delegate.initialize(aBaseType, String.class, Aspectj.class.getClassLoader(), inAWorld);
aBaseType.setDelegate(delegate);
}
public Aspectj() {
int N = 25;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i)
new Thread(new Worker(startSignal, doneSignal)).start();
startSignal.countDown();
try {
doneSignal.await();
} catch (InterruptedException e){
e.printStackTrace();
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void doWork() {
for (int i = 0; i < 10; i++) {
// using TypeFactory
TypeFactory.createParameterizedType(aBaseType, new ResolvedType[0], inAWorld);
// or creating ReferenceTypes directly
//new ReferenceType(aBaseType, new ResolvedType[0], inAWorld);
}
}
}
}
--- sample program end ---