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 ---

_______________________________________________
aspectj-users mailing list
aspectj-users@eclipse.org
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to