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