1.8.6 release prep 1.8.6 pom updates Fix rogue chars in javadoc rebuilt with javadoc fixestags/V1_8_7
/** | /** | ||||
* This class represents a stack map attribute used for preverification of Java classes for the <a href="http://java.sun.com/j2me/"> | * 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 | * 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 $ | * @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> | * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> |
/** | /** | ||||
* This class represents a stack map entry recording the types of | * 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. | * 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 $ | * @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> | * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> |
} | } | ||||
/** | /** | ||||
* 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) { | public boolean accessibleTo(ObjectType accessor) { | ||||
JavaClass jc = Repository.lookupClass(classname); | JavaClass jc = Repository.lookupClass(classname); |
*/ | */ | ||||
if (this instanceof ObjectType && ((ObjectType) this).referencesInterface()) { | 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 instanceof ObjectType && ((ObjectType) T).referencesClass()) { | ||||
if (T.equals(Type.OBJECT)) { | if (T.equals(Type.OBJECT)) { | ||||
} | } | ||||
/* | /* | ||||
* 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 (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { | ||||
if (this.equals(T)) { | if (this.equals(T)) { | ||||
*/ | */ | ||||
if (this instanceof ArrayType) { | 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 instanceof ObjectType && ((ObjectType) T).referencesClass()) { | ||||
if (T.equals(Type.OBJECT)) { | if (T.equals(Type.OBJECT)) { | ||||
*/ | */ | ||||
if (T instanceof ArrayType) { | 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 sc = ((ArrayType) this).getElementType(); | ||||
Type tc = ((ArrayType) this).getElementType(); | Type tc = ((ArrayType) this).getElementType(); | ||||
} | } | ||||
/* | /* | ||||
* 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 | if (tc instanceof ReferenceType && sc instanceof ReferenceType | ||||
&& ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { | && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { | ||||
} | } | ||||
} | } | ||||
/* 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 | // 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 | // interfaces arrays implement. However, as of the JVM specification edition 2, there | ||||
// are at least two different pages where assignment compatibility is defined and | // are at least two different pages where assignment compatibility is defined and | ||||
* t is an ArrayType, then Type.OBJECT is returned; unless their dimensions match. Then an ArrayType of the same number of | * 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" | * 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 | * 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) { | public ReferenceType getFirstCommonSuperclass(ReferenceType t) { | ||||
if (this.equals(Type.NULL)) { | if (this.equals(Type.NULL)) { | ||||
// * t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an interface, then | // * t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an interface, then | ||||
// Type.OBJECT | // Type.OBJECT | ||||
// * is returned. If not all of the two classes' superclasses cannot be found, "null" is returned. See the JVM specification | // * 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. | // * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has slightly changed semantics. | ||||
// */ | // */ |
/** | /** | ||||
* Returnaddress, the type JSR or JSR_W instructions push upon the stack. | * 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 $ | * @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> | * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase">Enver Haase</A> | ||||
*/ | */ |
<groupId>org.aspectj</groupId> | <groupId>org.aspectj</groupId> | ||||
<artifactId>aspectjrt</artifactId> | <artifactId>aspectjrt</artifactId> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<version>1.8.4.BUILD-SNAPSHOT</version> | |||||
<version>1.8.6.BUILD-SNAPSHOT</version> | |||||
<name>AspectJ runtime</name> | <name>AspectJ runtime</name> | ||||
<description>The runtime needed to execute a program using AspectJ</description> | <description>The runtime needed to execute a program using AspectJ</description> | ||||
<url>http://www.aspectj.org</url> | <url>http://www.aspectj.org</url> |
<groupId>org.aspectj</groupId> | <groupId>org.aspectj</groupId> | ||||
<artifactId>aspectjtools</artifactId> | <artifactId>aspectjtools</artifactId> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<version>1.8.4.BUILD-SNAPSHOT</version> | |||||
<version>1.8.6.BUILD-SNAPSHOT</version> | |||||
<name>AspectJ tools</name> | <name>AspectJ tools</name> | ||||
<description>Tools from the AspectJ project</description> | <description>Tools from the AspectJ project</description> | ||||
<url>http://www.aspectj.org</url> | <url>http://www.aspectj.org</url> |
<groupId>org.aspectj</groupId> | <groupId>org.aspectj</groupId> | ||||
<artifactId>aspectjweaver</artifactId> | <artifactId>aspectjweaver</artifactId> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<version>1.8.4.BUILD-SNAPSHOT</version> | |||||
<version>1.8.6.BUILD-SNAPSHOT</version> | |||||
<name>AspectJ weaver</name> | <name>AspectJ weaver</name> | ||||
<description>The AspectJ weaver introduces advices to java classes</description> | <description>The AspectJ weaver introduces advices to java classes</description> | ||||
<url>http://www.aspectj.org</url> | <url>http://www.aspectj.org</url> |
<groupId>org.aspectj</groupId> | <groupId>org.aspectj</groupId> | ||||
<artifactId>aspectjrt</artifactId> | <artifactId>aspectjrt</artifactId> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<version>1.8.4</version> | |||||
<version>1.8.6</version> | |||||
<name>AspectJ runtime</name> | <name>AspectJ runtime</name> | ||||
<description>The runtime needed to execute a program using AspectJ</description> | <description>The runtime needed to execute a program using AspectJ</description> | ||||
<url>http://www.aspectj.org</url> | <url>http://www.aspectj.org</url> |
<groupId>org.aspectj</groupId> | <groupId>org.aspectj</groupId> | ||||
<artifactId>aspectjtools</artifactId> | <artifactId>aspectjtools</artifactId> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<version>1.8.4</version> | |||||
<version>1.8.6</version> | |||||
<name>AspectJ tools</name> | <name>AspectJ tools</name> | ||||
<description>Tools from the AspectJ project</description> | <description>Tools from the AspectJ project</description> | ||||
<url>http://www.aspectj.org</url> | <url>http://www.aspectj.org</url> |
<groupId>org.aspectj</groupId> | <groupId>org.aspectj</groupId> | ||||
<artifactId>aspectjweaver</artifactId> | <artifactId>aspectjweaver</artifactId> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<version>1.8.4</version> | |||||
<version>1.8.6</version> | |||||
<name>AspectJ weaver</name> | <name>AspectJ weaver</name> | ||||
<description>The AspectJ weaver introduces advices to java classes</description> | <description>The AspectJ weaver introduces advices to java classes</description> | ||||
<url>http://www.aspectj.org</url> | <url>http://www.aspectj.org</url> |
<!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> |
<tr> <td>README's | <tr> <td>README's | ||||
</td> | </td> | ||||
<td>Changes and porting guide for AspectJ | <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-185.html">1.8.5</a>, | ||||
<a href="README-184.html">1.8.4</a>, | <a href="README-184.html">1.8.4</a>, | ||||
<a href="README-183.html">1.8.3</a>, | <a href="README-183.html">1.8.3</a>, |
import org.aspectj.util.FuzzyBoolean; | import org.aspectj.util.FuzzyBoolean; | ||||
import org.aspectj.weaver.CompressingDataOutputStream; | import org.aspectj.weaver.CompressingDataOutputStream; | ||||
import org.aspectj.weaver.IntMap; | import org.aspectj.weaver.IntMap; | ||||
import org.aspectj.weaver.ReferenceType; | |||||
import org.aspectj.weaver.ReferenceTypeDelegate; | |||||
import org.aspectj.weaver.ResolvedType; | import org.aspectj.weaver.ResolvedType; | ||||
import org.aspectj.weaver.Shadow; | import org.aspectj.weaver.Shadow; | ||||
import org.aspectj.weaver.World; | import org.aspectj.weaver.World; | ||||
import org.aspectj.weaver.patterns.IScope; | import org.aspectj.weaver.patterns.IScope; | ||||
import org.aspectj.weaver.patterns.PatternNodeVisitor; | import org.aspectj.weaver.patterns.PatternNodeVisitor; | ||||
import org.aspectj.weaver.patterns.Pointcut; | import org.aspectj.weaver.patterns.Pointcut; | ||||
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate; | |||||
import org.aspectj.weaver.reflect.ReflectionFastMatchInfo; | import org.aspectj.weaver.reflect.ReflectionFastMatchInfo; | ||||
import org.aspectj.weaver.reflect.ReflectionShadow; | import org.aspectj.weaver.reflect.ReflectionShadow; | ||||
import org.aspectj.weaver.reflect.ReflectionWorld; | import org.aspectj.weaver.reflect.ReflectionWorld; | ||||
*/ | */ | ||||
public FuzzyBoolean fastMatch(FastMatchInfo info) { | public FuzzyBoolean fastMatch(FastMatchInfo info) { | ||||
if (info instanceof ReflectionFastMatchInfo) { | 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 { | 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.MAYBE; | ||||
} | } | ||||
return FuzzyBoolean.fromBoolean(this.matcher.couldMatchJoinPointsInType(clazz, ((ReflectionFastMatchInfo) info).getMatchingContext())); | |||||
} | } | ||||
throw new IllegalStateException("Can only match user-extension pcds against Reflection FastMatchInfo objects"); | throw new IllegalStateException("Can only match user-extension pcds against Reflection FastMatchInfo objects"); | ||||
} | } |
import org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut; | import org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut; | ||||
import org.aspectj.weaver.reflect.ReflectionFastMatchInfo; | import org.aspectj.weaver.reflect.ReflectionFastMatchInfo; | ||||
import org.aspectj.weaver.reflect.ReflectionShadow; | import org.aspectj.weaver.reflect.ReflectionShadow; | ||||
import org.aspectj.weaver.reflect.ReflectionWorld; | |||||
import org.aspectj.weaver.reflect.ShadowMatchImpl; | import org.aspectj.weaver.reflect.ShadowMatchImpl; | ||||
import org.aspectj.weaver.tools.DefaultMatchingContext; | import org.aspectj.weaver.tools.DefaultMatchingContext; | ||||
import org.aspectj.weaver.tools.MatchingContext; | import org.aspectj.weaver.tools.MatchingContext; | ||||
public boolean couldMatchJoinPointsInType(Class aClass) { | public boolean couldMatchJoinPointsInType(Class aClass) { | ||||
ResolvedType matchType = world.resolve(aClass.getName()); | 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); | ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world); | ||||
boolean couldMatch = pointcut.fastMatch(info).maybeTrue(); | boolean couldMatch = pointcut.fastMatch(info).maybeTrue(); | ||||
if (MATCH_INFO) { | if (MATCH_INFO) { |
this.classLoaderReference = new WeakClassLoaderReference((aClassLoader != null) ? aClassLoader : bootClassLoader); | this.classLoaderReference = new WeakClassLoaderReference((aClassLoader != null) ? aClassLoader : bootClassLoader); | ||||
} | } | ||||
public Class<?> getClazz() { | |||||
return this.myClass; | |||||
} | |||||
protected Class getBaseClass() { | protected Class getBaseClass() { | ||||
return this.myClass; | return this.myClass; | ||||
} | } |
return null; | 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, | public static ReflectionBasedReferenceTypeDelegate create14Delegate(ReferenceType forReferenceType, World inWorld, | ||||
ClassLoader usingClassLoader) { | ClassLoader usingClassLoader) { |
* ******************************************************************/ | * ******************************************************************/ | ||||
package org.aspectj.weaver.reflect; | package org.aspectj.weaver.reflect; | ||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import org.aspectj.bridge.AbortException; | import org.aspectj.bridge.AbortException; | ||||
import org.aspectj.bridge.IMessage; | import org.aspectj.bridge.IMessage; | ||||
import org.aspectj.bridge.IMessageHandler; | import org.aspectj.bridge.IMessageHandler; | ||||
private WeakClassLoaderReference classLoaderReference; | private WeakClassLoaderReference classLoaderReference; | ||||
private AnnotationFinder annotationFinder; | private AnnotationFinder annotationFinder; | ||||
private boolean mustUseOneFourDelegates = false; // for testing | private boolean mustUseOneFourDelegates = false; // for testing | ||||
private Map<String,Class<?>> inProgressResolutionClasses = new HashMap<String,Class<?>>(); | |||||
private ReflectionWorld() { | private ReflectionWorld() { | ||||
// super(); | // super(); | ||||
return world.resolve(className); | 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) { | protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { | ||||
ReferenceTypeDelegate result; | |||||
if (mustUseOneFourDelegates) { | if (mustUseOneFourDelegates) { | ||||
return ReflectionBasedReferenceTypeDelegateFactory.create14Delegate(ty, this, classLoaderReference.getClassLoader()); | |||||
result = ReflectionBasedReferenceTypeDelegateFactory.create14Delegate(ty, this, classLoaderReference.getClassLoader()); | |||||
} else { | } 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 { | public static class ReflectionWorldException extends RuntimeException { |
<classpathentry kind="lib" path="/lib/bcel/bcel-verifier.jar"/> | <classpathentry kind="lib" path="/lib/bcel/bcel-verifier.jar"/> | ||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | <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="/org.aspectj.matcher"/> | ||||
<classpathentry combineaccessrules="false" kind="src" path="/weaver5"/> | |||||
<classpathentry kind="output" path="bin"/> | <classpathentry kind="output" path="bin"/> | ||||
</classpath> | </classpath> |
public class Application { | |||||
@Foo | |||||
Runnable fromInnerClass() { | |||||
return new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
} | |||||
}; | |||||
} | |||||
@Foo | |||||
Runnable fromLambdaExpression() { | |||||
return () -> { }; | |||||
} | |||||
} |
import java.lang.annotation.*; | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
@interface Foo {} |
package org.aspectj.systemtest.ajc186; | package org.aspectj.systemtest.ajc186; | ||||
import java.io.File; | import java.io.File; | ||||
import java.lang.reflect.Method; | |||||
import java.net.URL; | |||||
import java.net.URLClassLoader; | |||||
import junit.framework.Test; | import junit.framework.Test; | ||||
import org.aspectj.testing.XMLBasedAjcTestCase; | 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 | * @author Andy Clement | ||||
*/ | */ | ||||
public class Ajc186Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | 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 { | public void testMissingExtends() throws Exception { | ||||
runTest("missing extends on generic target"); | runTest("missing extends on generic target"); | ||||
} | } | ||||
public void testMissingMethod_462821() throws Exception { | public void testMissingMethod_462821() throws Exception { | ||||
runTest("missing method"); | runTest("missing method"); | ||||
} | } | ||||
@Override | @Override | ||||
protected File getSpecFile() { | protected File getSpecFile() { | ||||
return getClassResource("ajc186.xml"); | |||||
return getClassResource("ajc186.xml"); | |||||
} | } | ||||
} | } |
<suite> | <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"> | <ajc-test dir="bugs186/462821" title="missing method"> | ||||
<compile files="FooService.java AbstractLoggerAspect.java FooServiceLoggerAspect.java" options="-1.8"> | <compile files="FooService.java AbstractLoggerAspect.java FooServiceLoggerAspect.java" options="-1.8"> | ||||
</compile> | </compile> |