diff options
author | Andy Clement <aclement@pivotal.io> | 2015-05-26 15:12:55 -0700 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2015-06-08 08:35:23 -0700 |
commit | e1f6d1fc52d329b018ed11c08cab5011f267c3d0 (patch) | |
tree | f6e01041d784e766bc1a341c75701db454ea575e | |
parent | 066dc11d46731d5a60866dc1ded2dd3e3ef2fcd0 (diff) | |
download | aspectj-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
25 files changed, 288 insertions, 29 deletions
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java index 80f943bbf..29f9c1535 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java @@ -63,7 +63,7 @@ import org.aspectj.apache.bcel.Constants; /** * This class represents a stack map attribute used for preverification of Java classes for the <a href="http://java.sun.com/j2me/"> * Java 2 Micro Edition</a> (J2ME). This attribute is used by the <a href="http://java.sun.com/products/cldc/">KVM</a> and contained - * within the Code attribute of a method. See CLDC specification §5.3.1.2 + * within the Code attribute of a method. See CLDC specification 5.3.1.2 * * @version $Id: StackMap.java,v 1.6 2009/09/15 19:40:12 aclement Exp $ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java index b369083fb..76bb2ab79 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java @@ -61,7 +61,7 @@ import java.io.IOException; /** * This class represents a stack map entry recording the types of * local variables and the the of stack items at a given byte code offset. - * See CLDC specification §5.3.1.2 + * See CLDC specification 5.3.1.2 * * @version $Id: StackMapEntry.java,v 1.5 2008/05/28 23:53:02 aclement Exp $ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java index 95e467529..544363f16 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java @@ -146,7 +146,7 @@ public class ObjectType extends ReferenceType { } /** - * Java Virtual Machine Specification edition 2, § 5.4.4 Access Control + * Java Virtual Machine Specification edition 2, 5.4.4 Access Control */ public boolean accessibleTo(ObjectType accessor) { JavaClass jc = Repository.lookupClass(classname); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java index ae3be0c00..1e290f5a4 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java @@ -137,7 +137,7 @@ public abstract class ReferenceType extends Type { */ if (this instanceof ObjectType && ((ObjectType) this).referencesInterface()) { /* - * If T is a class type, then T must be Object (§2.4.7). + * If T is a class type, then T must be Object (2.4.7). */ if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { if (T.equals(Type.OBJECT)) { @@ -146,7 +146,7 @@ public abstract class ReferenceType extends Type { } /* - * If T is an interface type, then T must be the same interface as this or a superinterface of this (§2.13.2). + * If T is an interface type, then T must be the same interface as this or a superinterface of this (2.13.2). */ if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { if (this.equals(T)) { @@ -163,7 +163,7 @@ public abstract class ReferenceType extends Type { */ if (this instanceof ArrayType) { /* - * If T is a class type, then T must be Object (§2.4.7). + * If T is a class type, then T must be Object (2.4.7). */ if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { if (T.equals(Type.OBJECT)) { @@ -176,7 +176,7 @@ public abstract class ReferenceType extends Type { */ if (T instanceof ArrayType) { /* - * TC and SC are the same primitive type (§2.4.1). + * TC and SC are the same primitive type (2.4.1). */ Type sc = ((ArrayType) this).getElementType(); Type tc = ((ArrayType) this).getElementType(); @@ -186,7 +186,7 @@ public abstract class ReferenceType extends Type { } /* - * TC and SC are reference types (§2.4.6), and type SC is assignable to TC by these runtime rules. + * TC and SC are reference types (2.4.6), and type SC is assignable to TC by these runtime rules. */ if (tc instanceof ReferenceType && sc instanceof ReferenceType && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { @@ -194,7 +194,7 @@ public abstract class ReferenceType extends Type { } } - /* If T is an interface type, T must be one of the interfaces implemented by arrays (§2.15). */ + /* If T is an interface type, T must be one of the interfaces implemented by arrays (2.15). */ // TODO: Check if this is still valid or find a way to dynamically find out which // interfaces arrays implement. However, as of the JVM specification edition 2, there // are at least two different pages where assignment compatibility is defined and @@ -218,7 +218,7 @@ public abstract class ReferenceType extends Type { * t is an ArrayType, then Type.OBJECT is returned; unless their dimensions match. Then an ArrayType of the same number of * dimensions is returned, with its basic type being the first common super class of the basic types of "this" and t. If "this" * or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. If not all of the two classes' superclasses - * cannot be found, "null" is returned. See the JVM specification edition 2, "§4.9.2 The Bytecode Verifier". + * cannot be found, "null" is returned. See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". */ public ReferenceType getFirstCommonSuperclass(ReferenceType t) { if (this.equals(Type.NULL)) { @@ -300,7 +300,7 @@ public abstract class ReferenceType extends Type { // * t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an interface, then // Type.OBJECT // * is returned. If not all of the two classes' superclasses cannot be found, "null" is returned. See the JVM specification - // * edition 2, "§4.9.2 The Bytecode Verifier". + // * edition 2, "4.9.2 The Bytecode Verifier". // * // * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has slightly changed semantics. // */ diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java index 45ffae9b7..a38ffedfd 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java @@ -59,7 +59,7 @@ import org.aspectj.apache.bcel.generic.InstructionHandle; /** * Returnaddress, the type JSR or JSR_W instructions push upon the stack. * - * see vmspec2 §3.3.3 + * see vmspec2 3.3.3 * @version $Id: ReturnaddressType.java,v 1.3 2008/05/28 23:52:56 aclement Exp $ * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase">Enver Haase</A> */ diff --git a/build/usedForMavenUpload/aspectjrt.pom b/build/usedForMavenUpload/aspectjrt.pom index 25c6146d7..5178898a6 100644 --- a/build/usedForMavenUpload/aspectjrt.pom +++ b/build/usedForMavenUpload/aspectjrt.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <packaging>jar</packaging> - <version>1.8.4.BUILD-SNAPSHOT</version> + <version>1.8.6.BUILD-SNAPSHOT</version> <name>AspectJ runtime</name> <description>The runtime needed to execute a program using AspectJ</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload/aspectjtools.pom b/build/usedForMavenUpload/aspectjtools.pom index defa88acf..2c536f4fc 100644 --- a/build/usedForMavenUpload/aspectjtools.pom +++ b/build/usedForMavenUpload/aspectjtools.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <packaging>jar</packaging> - <version>1.8.4.BUILD-SNAPSHOT</version> + <version>1.8.6.BUILD-SNAPSHOT</version> <name>AspectJ tools</name> <description>Tools from the AspectJ project</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload/aspectjweaver.pom b/build/usedForMavenUpload/aspectjweaver.pom index ad82e4093..d681a3e73 100644 --- a/build/usedForMavenUpload/aspectjweaver.pom +++ b/build/usedForMavenUpload/aspectjweaver.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <packaging>jar</packaging> - <version>1.8.4.BUILD-SNAPSHOT</version> + <version>1.8.6.BUILD-SNAPSHOT</version> <name>AspectJ weaver</name> <description>The AspectJ weaver introduces advices to java classes</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload_release/aspectjrt.pom b/build/usedForMavenUpload_release/aspectjrt.pom index 2cb2521e1..f745bce1f 100644 --- a/build/usedForMavenUpload_release/aspectjrt.pom +++ b/build/usedForMavenUpload_release/aspectjrt.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <packaging>jar</packaging> - <version>1.8.4</version> + <version>1.8.6</version> <name>AspectJ runtime</name> <description>The runtime needed to execute a program using AspectJ</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload_release/aspectjtools.pom b/build/usedForMavenUpload_release/aspectjtools.pom index f78b536cd..50526540a 100644 --- a/build/usedForMavenUpload_release/aspectjtools.pom +++ b/build/usedForMavenUpload_release/aspectjtools.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <packaging>jar</packaging> - <version>1.8.4</version> + <version>1.8.6</version> <name>AspectJ tools</name> <description>Tools from the AspectJ project</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload_release/aspectjweaver.pom b/build/usedForMavenUpload_release/aspectjweaver.pom index e4ffc6e1b..d9d49848f 100644 --- a/build/usedForMavenUpload_release/aspectjweaver.pom +++ b/build/usedForMavenUpload_release/aspectjweaver.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <packaging>jar</packaging> - <version>1.8.4</version> + <version>1.8.6</version> <name>AspectJ weaver</name> <description>The AspectJ weaver introduces advices to java classes</description> <url>http://www.aspectj.org</url> diff --git a/docs/dist/doc/README-186.html b/docs/dist/doc/README-186.html new file mode 100644 index 000000000..e9d57f5f8 --- /dev/null +++ b/docs/dist/doc/README-186.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> <head> +<title>AspectJ 1.8.6 Readme</title> +<style type="text/css"> +<!-- + P { margin-left: 20px; } + PRE { margin-left: 20px; } + LI { margin-left: 20px; } + H4 { margin-left: 20px; } + H3 { margin-left: 10px; } +--> +</style> +</head> + +<body> +<div align="right"><small> +© Copyright 2015 Contributors. +All rights reserved. +</small></div> + +<h1>AspectJ 1.8.6 Readme</h1> + +<p>The full list of resolved issues in 1.8.6 is available +<a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED;product=AspectJ;target_milestone=1.8.6;">here</a></h2>.</p> + +<ul> +<li>1.8.6 available 5-Jun-2015 +</ul> + +<!-- +<h2>Notable changes</h2> +--> + +<!-- ============================== --> +</body> +</html> diff --git a/docs/dist/doc/index.html b/docs/dist/doc/index.html index fabaf0d0a..a3167b50a 100644 --- a/docs/dist/doc/index.html +++ b/docs/dist/doc/index.html @@ -138,6 +138,7 @@ <tr> <td>README's </td> <td>Changes and porting guide for AspectJ + <a href="README-186.html">1.8.6</a>, <a href="README-185.html">1.8.5</a>, <a href="README-184.html">1.8.4</a>, <a href="README-183.html">1.8.3</a>, diff --git a/lib/bcel/bcel-src.zip b/lib/bcel/bcel-src.zip Binary files differindex 3881b662f..6e51d7916 100644 --- a/lib/bcel/bcel-src.zip +++ b/lib/bcel/bcel-src.zip diff --git a/lib/bcel/bcel.jar b/lib/bcel/bcel.jar Binary files differindex 0126d477e..040e5d0b5 100644 --- a/lib/bcel/bcel.jar +++ b/lib/bcel/bcel.jar 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 { diff --git a/tests/.classpath b/tests/.classpath index 864376023..bd87c250e 100644 --- a/tests/.classpath +++ b/tests/.classpath @@ -17,5 +17,6 @@ <classpathentry kind="lib" path="/lib/bcel/bcel-verifier.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry combineaccessrules="false" kind="src" path="/org.aspectj.matcher"/> + <classpathentry combineaccessrules="false" kind="src" path="/weaver5"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/tests/bugs186/lambdaBeans/Application.java b/tests/bugs186/lambdaBeans/Application.java new file mode 100644 index 000000000..f98a49a5e --- /dev/null +++ b/tests/bugs186/lambdaBeans/Application.java @@ -0,0 +1,16 @@ +public class Application { + + @Foo + Runnable fromInnerClass() { + return new Runnable() { + @Override + public void run() { + } + }; + } + + @Foo + Runnable fromLambdaExpression() { + return () -> { }; + } +} diff --git a/tests/bugs186/lambdaBeans/Foo.java b/tests/bugs186/lambdaBeans/Foo.java new file mode 100644 index 000000000..60e42f6e2 --- /dev/null +++ b/tests/bugs186/lambdaBeans/Foo.java @@ -0,0 +1,4 @@ +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@interface Foo {} diff --git a/tests/src/org/aspectj/systemtest/ajc186/Ajc186Tests.java b/tests/src/org/aspectj/systemtest/ajc186/Ajc186Tests.java index aeb6c1621..1625f96d1 100644 --- a/tests/src/org/aspectj/systemtest/ajc186/Ajc186Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc186/Ajc186Tests.java @@ -11,20 +11,139 @@ package org.aspectj.systemtest.ajc186; import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; import junit.framework.Test; import org.aspectj.testing.XMLBasedAjcTestCase; +import org.aspectj.weaver.tools.ContextBasedMatcher; +import org.aspectj.weaver.tools.DefaultMatchingContext; +import org.aspectj.weaver.tools.FuzzyBoolean; +import org.aspectj.weaver.tools.MatchingContext; +import org.aspectj.weaver.tools.PointcutDesignatorHandler; +import org.aspectj.weaver.tools.PointcutExpression; +import org.aspectj.weaver.tools.PointcutParser; /** * @author Andy Clement */ public class Ajc186Tests extends org.aspectj.testing.XMLBasedAjcTestCase { + private class FooDesignatorHandler implements PointcutDesignatorHandler { + + private String askedToParse; + public boolean simulateDynamicTest = false; + + public String getDesignatorName() { + return "foo"; + } + + public ContextBasedMatcher parse(String expression) { + this.askedToParse = expression; + return new FooPointcutExpression(expression, this.simulateDynamicTest); + } + + public String getExpressionLastAskedToParse() { + return this.askedToParse; + } + } + + private class FooPointcutExpression implements ContextBasedMatcher { + + private final String beanNamePattern; + private final boolean simulateDynamicTest; + + public FooPointcutExpression(String beanNamePattern, + boolean simulateDynamicTest) { + this.beanNamePattern = beanNamePattern; + this.simulateDynamicTest = simulateDynamicTest; + } + + public boolean couldMatchJoinPointsInType(Class aClass) { + System.out.println("wubble?"); + return true; + } + + public boolean couldMatchJoinPointsInType(Class aClass, + MatchingContext context) { + System.out.println("wibble?"); + if (this.beanNamePattern.equals(context.getBinding("beanName"))) { + return true; + } else { + return false; + } + } + + public boolean mayNeedDynamicTest() { + return this.simulateDynamicTest; + } + + public FuzzyBoolean matchesStatically(MatchingContext matchContext) { + System.out.println("wobble?"); + if (this.simulateDynamicTest) + return FuzzyBoolean.MAYBE; + if (this.beanNamePattern + .equals(matchContext.getBinding("beanName"))) { + return FuzzyBoolean.YES; + } else { + return FuzzyBoolean.NO; + } + } + + public boolean matchesDynamically(MatchingContext matchContext) { + System.out.println("wabble?"); + return this.beanNamePattern.equals(matchContext + .getBinding("beanName")); + } + } + + public void testLambdaBeans() throws Exception { + runTest("lambda beans"); + + // Load the 1.8 compiled code + URLClassLoader ucl = new URLClassLoader(new URL[] {ajc.getSandboxDirectory().toURI().toURL()},this.getClass().getClassLoader()); + Class<?> applicationClass = Class.forName("Application",false,ucl); + assertNotNull(applicationClass); + Object instance = applicationClass.newInstance(); + Method works = applicationClass.getDeclaredMethod("fromInnerClass"); + works.setAccessible(true); + Runnable r = (Runnable) works.invoke(instance); + // r.getClass().getName() == Application$1 + + Method fails = applicationClass.getDeclaredMethod("fromLambdaExpression"); + fails.setAccessible(true); + Runnable r2 = (Runnable) fails.invoke(instance); + // r2.getClass().getName() == Application$$Lambda$1/1652149987 + +// JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), "Application"); + PointcutParser parser = PointcutParser + .getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(ucl); + FooDesignatorHandler beanHandler = new FooDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + PointcutExpression pc = parser.parsePointcutExpression("foo(myBean)"); + DefaultMatchingContext context = new DefaultMatchingContext(); + pc.setMatchingContext(context); + + context.addContextBinding("beanName", "myBean"); + assertTrue(pc.couldMatchJoinPointsInType(r.getClass())); + + context.addContextBinding("beanName", "yourBean"); + assertFalse(pc.couldMatchJoinPointsInType(r.getClass())); + + context.addContextBinding("beanName", "myBean"); + assertTrue(pc.couldMatchJoinPointsInType(r2.getClass())); + + context.addContextBinding("beanName", "yourBean"); + assertFalse(pc.couldMatchJoinPointsInType(r2.getClass())); + } + + public void testMissingExtends() throws Exception { runTest("missing extends on generic target"); } - + public void testMissingMethod_462821() throws Exception { runTest("missing method"); } @@ -37,7 +156,7 @@ public class Ajc186Tests extends org.aspectj.testing.XMLBasedAjcTestCase { @Override protected File getSpecFile() { - return getClassResource("ajc186.xml"); + return getClassResource("ajc186.xml"); } } diff --git a/tests/src/org/aspectj/systemtest/ajc186/ajc186.xml b/tests/src/org/aspectj/systemtest/ajc186/ajc186.xml index 69d0e0c05..4f1394a95 100644 --- a/tests/src/org/aspectj/systemtest/ajc186/ajc186.xml +++ b/tests/src/org/aspectj/systemtest/ajc186/ajc186.xml @@ -2,6 +2,11 @@ <suite> +<ajc-test dir="bugs186/lambdaBeans" title="lambda beans"> +<compile files="Foo.java Application.java" options="-1.8"> +</compile> +</ajc-test> + <ajc-test dir="bugs186/462821" title="missing method"> <compile files="FooService.java AbstractLoggerAspect.java FooServiceLoggerAspect.java" options="-1.8"> </compile> |