aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.matcher
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2015-05-26 15:12:55 -0700
committerAndy Clement <aclement@pivotal.io>2015-06-08 08:35:23 -0700
commite1f6d1fc52d329b018ed11c08cab5011f267c3d0 (patch)
treef6e01041d784e766bc1a341c75701db454ea575e /org.aspectj.matcher
parent066dc11d46731d5a60866dc1ded2dd3e3ef2fcd0 (diff)
downloadaspectj-e1f6d1fc52d329b018ed11c08cab5011f267c3d0.tar.gz
aspectj-e1f6d1fc52d329b018ed11c08cab5011f267c3d0.zip
allow reflection world to resolve generated types (e.g. lambdas)
1.8.6 release prep 1.8.6 pom updates Fix rogue chars in javadoc rebuilt with javadoc fixes
Diffstat (limited to 'org.aspectj.matcher')
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutDesignatorHandlerBasedPointcut.java26
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java7
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java4
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java11
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java47
5 files changed, 86 insertions, 9 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutDesignatorHandlerBasedPointcut.java b/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutDesignatorHandlerBasedPointcut.java
index 9c508a1a3..e5672dede 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutDesignatorHandlerBasedPointcut.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutDesignatorHandlerBasedPointcut.java
@@ -17,6 +17,8 @@ import java.util.Map;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ReferenceTypeDelegate;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.World;
@@ -28,6 +30,7 @@ import org.aspectj.weaver.patterns.FastMatchInfo;
import org.aspectj.weaver.patterns.IScope;
import org.aspectj.weaver.patterns.PatternNodeVisitor;
import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
import org.aspectj.weaver.reflect.ReflectionFastMatchInfo;
import org.aspectj.weaver.reflect.ReflectionShadow;
import org.aspectj.weaver.reflect.ReflectionWorld;
@@ -64,16 +67,25 @@ public class PointcutDesignatorHandlerBasedPointcut extends Pointcut {
*/
public FuzzyBoolean fastMatch(FastMatchInfo info) {
if (info instanceof ReflectionFastMatchInfo) {
+ // Really need a reflectionworld here...
+ if (!(world instanceof ReflectionWorld)) {
+ throw new IllegalStateException("Can only match user-extension pcds with a ReflectionWorld");
+ }
+ Class<?> clazz = null;
try {
- // Really need a reflectionworld here...
- if (!(world instanceof ReflectionWorld)) {
- throw new IllegalStateException("Can only match user-extension pcds with a ReflectionWorld");
- }
- return FuzzyBoolean.fromBoolean(this.matcher.couldMatchJoinPointsInType(Class.forName(info.getType().getName(),
- false, ((ReflectionWorld) world).getClassLoader()), ((ReflectionFastMatchInfo) info).getMatchingContext()));
- } catch (ClassNotFoundException cnfEx) {
+ clazz = Class.forName(info.getType().getName(), false, ((ReflectionWorld) world).getClassLoader());
+ } catch (ClassNotFoundException cnfe) {
+ if (info.getType() instanceof ReferenceType) {
+ ReferenceTypeDelegate rtd = ((ReferenceType)info.getType()).getDelegate();
+ if (rtd instanceof ReflectionBasedReferenceTypeDelegate) {
+ clazz = ((ReflectionBasedReferenceTypeDelegate)rtd).getClazz();
+ }
+ }
+ }
+ if (clazz == null) {
return FuzzyBoolean.MAYBE;
}
+ return FuzzyBoolean.fromBoolean(this.matcher.couldMatchJoinPointsInType(clazz, ((ReflectionFastMatchInfo) info).getMatchingContext()));
}
throw new IllegalStateException("Can only match user-extension pcds against Reflection FastMatchInfo objects");
}
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java b/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java
index 1869e9b19..822c78d9a 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java
@@ -35,6 +35,7 @@ import org.aspectj.weaver.patterns.WithinAnnotationPointcut;
import org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut;
import org.aspectj.weaver.reflect.ReflectionFastMatchInfo;
import org.aspectj.weaver.reflect.ReflectionShadow;
+import org.aspectj.weaver.reflect.ReflectionWorld;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.DefaultMatchingContext;
import org.aspectj.weaver.tools.MatchingContext;
@@ -80,6 +81,12 @@ public class PointcutExpressionImpl implements PointcutExpression {
public boolean couldMatchJoinPointsInType(Class aClass) {
ResolvedType matchType = world.resolve(aClass.getName());
+ if (matchType.isMissing() && (world instanceof ReflectionWorld)) {
+ // Class is a generated class that cannot be 'looked up' via getResource.
+ // For example a proxy or lambda.
+ // Use the class itself in this case
+ matchType = ((ReflectionWorld)world).resolveUsingClass(aClass);
+ }
ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world);
boolean couldMatch = pointcut.fastMatch(info).maybeTrue();
if (MATCH_INFO) {
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java
index 988239e98..6110e6ceb 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java
@@ -69,6 +69,10 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
this.classLoaderReference = new WeakClassLoaderReference((aClassLoader != null) ? aClassLoader : bootClassLoader);
}
+ public Class<?> getClazz() {
+ return this.myClass;
+ }
+
protected Class getBaseClass() {
return this.myClass;
}
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java
index e1d709dfc..eee1b6f32 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java
@@ -47,6 +47,17 @@ public class ReflectionBasedReferenceTypeDelegateFactory {
return null;
}
}
+
+ public static ReflectionBasedReferenceTypeDelegate createDelegate(ReferenceType forReferenceType, World inWorld,
+ Class<?> clazz) {
+ if (LangUtil.is15VMOrGreater()) {
+ ReflectionBasedReferenceTypeDelegate rbrtd = create15Delegate(forReferenceType, clazz, clazz.getClassLoader(), inWorld);
+ if (rbrtd != null) {
+ return rbrtd; // can be null if we didn't find the class the delegate logic loads
+ }
+ }
+ return new ReflectionBasedReferenceTypeDelegate(clazz, clazz.getClassLoader(), inWorld, forReferenceType);
+ }
public static ReflectionBasedReferenceTypeDelegate create14Delegate(ReferenceType forReferenceType, World inWorld,
ClassLoader usingClassLoader) {
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java
index 64b8d4bb0..98e800222 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java
@@ -11,6 +11,9 @@
* ******************************************************************/
package org.aspectj.weaver.reflect;
+import java.util.HashMap;
+import java.util.Map;
+
import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHandler;
@@ -34,6 +37,7 @@ public class ReflectionWorld extends World implements IReflectionWorld {
private WeakClassLoaderReference classLoaderReference;
private AnnotationFinder annotationFinder;
private boolean mustUseOneFourDelegates = false; // for testing
+ private Map<String,Class<?>> inProgressResolutionClasses = new HashMap<String,Class<?>>();
private ReflectionWorld() {
// super();
@@ -105,13 +109,52 @@ public class ReflectionWorld extends World implements IReflectionWorld {
return world.resolve(className);
}
}
+
+ /**
+ * Resolve a type using the specified class. Normal resolution in a reflection
+ * world uses Class.forName() via the classloader (attached to this world)
+ * in order to find a named type then builds a reference type and a reference
+ * type delegate based on that. For some classes generated at runtime (e.g.
+ * proxy or lambda representation) the forName() call will not work. In those
+ * situations we should just use the clazz we have.
+ *
+ * Should the whole thing switch from using forName() to using the clazz objects?
+ * Possibly but that introduces a lot of change and we don't have a lot
+ * of test coverage for this scenario (reflection world). What we are doing
+ * right now is that this can optionally be used if the regular resolution
+ * scheme did not work.
+ *
+ * Although AspectJ is *not* multi threaded or re-entrant, Spring doesn't
+ * always respect that. There might be an issue here if two attempts are
+ * made to resolve the same thing at the same time via this method.
+ *
+ * @param clazz the class to use as the delegate for the resolved type
+ */
+ public ResolvedType resolveUsingClass(Class<?> clazz) {
+ String signature = UnresolvedType.forName(clazz.getName()).getSignature();
+ try {
+ inProgressResolutionClasses.put(signature, clazz);
+ return resolve(clazz.getName());
+ } finally {
+ inProgressResolutionClasses.remove(signature);
+ }
+ }
protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
+ ReferenceTypeDelegate result;
if (mustUseOneFourDelegates) {
- return ReflectionBasedReferenceTypeDelegateFactory.create14Delegate(ty, this, classLoaderReference.getClassLoader());
+ result = ReflectionBasedReferenceTypeDelegateFactory.create14Delegate(ty, this, classLoaderReference.getClassLoader());
} else {
- return ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, this, classLoaderReference.getClassLoader());
+ result = ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, this, classLoaderReference.getClassLoader());
+ }
+ if (result == null && inProgressResolutionClasses.size() != 0) {
+ // Is it a class that cannot be loaded (i.e. it was generated) but we already know about?
+ Class<?> clazz = inProgressResolutionClasses.get(ty.getSignature());
+ if (clazz != null) {
+ result = ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty,this,clazz);
+ }
}
+ return result;
}
public static class ReflectionWorldException extends RuntimeException {