View | Details | Raw Unified | Return to bug 114083
Collapse All | Expand All

(-)LTWWorld.java (-40 / +152 lines)
Lines 11-28 Link Here
11
 * ******************************************************************/
11
 * ******************************************************************/
12
package org.aspectj.weaver.ltw;
12
package org.aspectj.weaver.ltw;
13
13
14
import org.aspectj.weaver.Advice;
14
import java.lang.ref.WeakReference;
15
import org.aspectj.weaver.ConcreteTypeMunger;
15
import java.lang.reflect.InvocationTargetException;
16
import org.aspectj.weaver.Member;
16
import java.lang.reflect.Method;
17
import java.util.Collections;
18
import java.util.HashSet;
19
import java.util.Iterator;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.WeakHashMap;
23
24
import org.aspectj.bridge.IMessageHandler;
25
import org.aspectj.weaver.ICrossReferenceHandler;
17
import org.aspectj.weaver.ReferenceType;
26
import org.aspectj.weaver.ReferenceType;
18
import org.aspectj.weaver.ReferenceTypeDelegate;
27
import org.aspectj.weaver.ReferenceTypeDelegate;
19
import org.aspectj.weaver.ResolvedMember;
28
import org.aspectj.weaver.UnresolvedType;
20
import org.aspectj.weaver.ResolvedType;
29
import org.aspectj.weaver.bcel.BcelWorld;
21
import org.aspectj.weaver.ResolvedTypeMunger;
30
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegateFactory;
22
import org.aspectj.weaver.World;
31
import org.aspectj.weaver.reflect.ReflectionWorld;
23
import org.aspectj.weaver.AjAttribute.AdviceAttribute;
24
import org.aspectj.weaver.patterns.Pointcut;
25
import org.aspectj.weaver.patterns.PerClause.Kind;
26
32
27
/**
33
/**
28
 * @author adrian
34
 * @author adrian
Lines 40-76 Link Here
40
 * 
46
 * 
41
 * Create by passing in a classloader, message handler
47
 * Create by passing in a classloader, message handler
42
 */
48
 */
43
public class LTWWorld extends World {
49
public class LTWWorld extends BcelWorld {
44
50
	private ReflectionWorld reflectionWorld;
51
	private ClassLoader loader;
52
	//optimizations: use ConcurrentMap for Java 1.5...
53
	private static Map/*<ClassLoader, LTWWorld>*/ worlds = Collections.synchronizedMap(new WeakHashMap());
54
	
55
	private Set/*<WeakReference<LTWWorld>>*/ children = Collections.synchronizedSet(new HashSet());
56
	
57
	/**
58
     * Build a World from a ClassLoader, for LTW support
59
     *
60
     * @param loader
61
     * @param handler
62
     * @param xrefHandler
63
     */
64
    public LTWWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) {
65
    	super(loader, handler, xrefHandler);
66
    	this.loader = loader;
67
		reflectionWorld = new ReflectionWorld(loader);
68
		worlds.put(loader, this);
69
		if (loader.getParent() != null) {
70
			WeakReference ref = (WeakReference)worlds.get(loader.getParent());
71
			if (ref != null) {
72
				LTWWorld parentWorld = (LTWWorld)ref.get();
73
				if (parentWorld != null) {
74
					parentWorld.children.add(new WeakReference(this));
75
				}
76
			}
77
		}
78
    }
79
80
    /**
81
     * Reflective method to find a loaded class without loading if not found.
82
     */
83
    private final static Method findLoadedClassMethod = getLoadedClassMethod();
84
    private static Method getLoadedClassMethod() {
85
    	try {
86
    		Method findLoadedClassMethod = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[] { String.class });
87
    		findLoadedClassMethod.setAccessible(true);
88
    		return findLoadedClassMethod;
89
    	} catch (Throwable t) {
90
    		//swallow
91
    		return null;
92
    	}
93
    }
94
    
95
    /**
96
     * ThreadLocal holder of single argument array to hold class name, for efficiency. 
97
     */
98
    private final static ThreadLocal/*<String[]>*/ nameHolderHolder = new ThreadLocal() {
99
    	public Object initialValue() {
100
        	return new String[1]; 
101
    	}
102
    };
103
104
    /**
105
     * @Override
106
     */
45
	protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
107
	protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
46
		// TODO Auto-generated method stub
47
		return null;
48
		
108
		
109
	    String name = ty.getName();
110
	    
111
	    // first check for anything available in the bootstrap loader should be just defined from that without allowing nondelegation?
112
	    ReferenceTypeDelegate bootstrapLoaderDelegate = resolveReflectionTypeDelegate(ty, null);
113
	    if (bootstrapLoaderDelegate != null) {
114
	    	// it's always fine to load these bytes: there's no weaving from them
115
	    	// and since the class isn't initialized, all we are doing at this point is loading the bytes
116
	    	return bootstrapLoaderDelegate;	    		
117
	    }
118
    	// indeed for ANY class loader with a disabled weaver, this is fine too!
119
    	// this is a potentially BIG optimization: just loading a reflection delegate for any type that can't be woven
120
	    
121
	    // failing this, we look to see whether the class has already been loaded
122
	    ClassLoader resolutionLoader = loader;
123
		String asRes = name.replace('.', '/').concat(".class");
124
		java.net.URL resURL = resolutionLoader.getResource(asRes);
125
	    boolean tryAgain;
126
	    String[] arg = (String[])nameHolderHolder.get();
127
	    arg[0] = name;
128
	    
129
	    do {
130
		    try {
131
				Class clazz = (Class)findLoadedClassMethod.invoke(resolutionLoader, arg);
132
				if (clazz != null) {
133
					return resolveReflectionTypeDelegate(ty, resolutionLoader);
134
				}
135
				
136
			} catch (IllegalArgumentException e) {
137
			} catch (IllegalAccessException e) {
138
			} catch (InvocationTargetException e) {
139
			}
140
			
141
			if (resolutionLoader != null) {
142
				// can my parent resolve this?
143
				// will I resolve this by delegating to my parent?
144
				java.net.URL parentURL = resolutionLoader.getParent().getResource(asRes);
145
				tryAgain = (parentURL != null && parentURL.equals(resURL));
146
				resolutionLoader = resolutionLoader.getParent();
147
			} else {
148
				tryAgain = false;
149
			}
150
			
151
	    } while (tryAgain);
152
	    //TODO: can we somehow avoid creating many aliases, one per child ClassLoader?
153
		return super.resolveDelegate(ty);
154
	}
155
156
	/**
157
	 * Helper method to resolve the delegate from the reflection delegate factory.
158
	 */
159
	private ReferenceTypeDelegate resolveReflectionTypeDelegate(ReferenceType ty, ClassLoader resolutionLoader) {
160
		ReferenceTypeDelegate res = ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, reflectionWorld, resolutionLoader);
161
		return res;
162
	}
163
164
	/**
165
	 * Remove this class from the typeMap. 
166
	 * When next needed, a reflective proxy will be created: no need to create it eagerly...
167
	 * TODO: test 
168
	 * 
169
	 * @param clazz
170
	 */
171
	public void loadedClass(Class clazz) {
172
		// evict it from the parent
173
		typeMap.remove(UnresolvedType.forName(clazz.getName()).getSignature());
174
		
175
		// and all the children...
176
		for (Iterator it = children.iterator(); it.hasNext();) {
177
			WeakReference ref = (WeakReference)it.next();
178
			if (ref != null) {
179
				LTWWorld world = (LTWWorld)ref.get();
180
				if (world != null) {
181
					world.loadedClass(clazz);
182
				}
183
			}			
184
		}
49
	}
185
	}
50
186
	
51
	public Advice createAdviceMunger(AdviceAttribute attribute, Pointcut pointcut, Member signature) {
187
	private static final long serialVersionUID = 1;
52
		// TODO Auto-generated method stub
53
		return null;
54
	}
55
56
	public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) {
57
		// TODO Auto-generated method stub
58
		return null;
59
	}
60
61
	public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) {
62
		// TODO Auto-generated method stub
63
		return null;
64
	}
65
66
	public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, Kind kind) {
67
		// TODO Auto-generated method stub
68
		return null;
69
	}
70
71
	public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) {
72
		// TODO Auto-generated method stub
73
		return null;
74
	}
75
76
}
188
}

Return to bug 114083