diff options
7 files changed, 113 insertions, 9 deletions
diff --git a/weaver/src/org/aspectj/weaver/AjAttribute.java b/weaver/src/org/aspectj/weaver/AjAttribute.java index ed14f5865..77909614a 100644 --- a/weaver/src/org/aspectj/weaver/AjAttribute.java +++ b/weaver/src/org/aspectj/weaver/AjAttribute.java @@ -19,7 +19,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.MessageUtil; import org.aspectj.util.FileUtil; +import org.aspectj.weaver.bcel.BcelWorld; import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.PerClause; import org.aspectj.weaver.patterns.Pointcut; @@ -81,7 +84,7 @@ public abstract class AjAttribute { } } - public static AjAttribute read(String name, byte[] bytes, ISourceContext context) { + public static AjAttribute read(String name, byte[] bytes, ISourceContext context,IMessageHandler msgHandler) { try { if (bytes == null) bytes = new byte[0]; DataInputStream s = new DataInputStream(new ByteArrayInputStream(bytes)); @@ -91,6 +94,8 @@ public abstract class AjAttribute { return MethodDeclarationLineNumberAttribute.read(s); } else if (name.equals(WeaverState.AttributeName)) { return new WeaverState(WeaverStateInfo.read(s, context)); + } else if (name.equals(WeaverVersionInfo.AttributeName)) { + return WeaverVersionInfo.read(s); } else if (name.equals(AdviceAttribute.AttributeName)) { return AdviceAttribute.read(s, context); } else if (name.equals(PointcutDeclarationAttribute.AttributeName)) { @@ -108,7 +113,10 @@ public abstract class AjAttribute { } else if (name.equals(EffectiveSignatureAttribute.AttributeName)) { return EffectiveSignatureAttribute.read(s, context); } else { - throw new BCException("unknown attribute" + name); + // We have to tell the user about this... + if (msgHandler == null) throw new BCException("unknown attribute" + name); + msgHandler.handleMessage(MessageUtil.warn("unknown attribute encountered "+name)); + return null; } } catch (IOException e) { throw new BCException("malformed " + name + " attribute " + e); @@ -177,6 +185,82 @@ public abstract class AjAttribute { } } + public static class WeaverVersionInfo extends AjAttribute { + public static final String AttributeName = "org.aspectj.weaver.WeaverVersion"; + + // If you change the format of an AspectJ class file, you have two options: + // - changing the minor version means you have not added anything that prevents + // previous versions of the weaver from operating (e.g. MethodDeclarationLineNumber attribute) + // - changing the major version means you have added something that prevents previous + // versions of the weaver from operating correctly. + // + // The user will get a warning for any org.aspectj.weaver attributes the weaver does + // not recognize. + + // These are the weaver major/minor numbers for AspectJ 1.2.1 + private static short WEAVER_VERSION_MAJOR_AJ121 = 1; + private static short WEAVER_VERSION_MINOR_AJ121 = 0; + + // These are the weaver major/minor versions for *this* weaver + private static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ121; + private static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ121; + + // These are the versions read in from a particular class file. + private short major_version; + private short minor_version; + + public String getNameString() { + return AttributeName; + } + + // Default ctor uses the current version numbers + public WeaverVersionInfo() { + this.major_version = CURRENT_VERSION_MAJOR; + this.minor_version = CURRENT_VERSION_MINOR; + } + + public WeaverVersionInfo(short major,short minor) { + major_version = major; + minor_version = minor; + } + + public void write(DataOutputStream s) throws IOException { + s.writeShort(CURRENT_VERSION_MAJOR); + s.writeShort(CURRENT_VERSION_MINOR); + } + + public static WeaverVersionInfo read(DataInputStream s) throws IOException { + short major = s.readShort(); + short minor = s.readShort(); + return new WeaverVersionInfo(major,minor); + } + + public short getMajorVersion() { + return major_version; + } + + public short getMinorVersion() { + return minor_version; + } + + public static short getCurrentWeaverMajorVersion() { + return CURRENT_VERSION_MAJOR; + } + + public static short getCurrentWeaverMinorVersion() { + return CURRENT_VERSION_MINOR; + } + + public String toString() { + return major_version+"."+minor_version; + } + + public static String toCurrentVersionString() { + return CURRENT_VERSION_MAJOR+"."+CURRENT_VERSION_MINOR; + } + + } + public static class SourceContextAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.SourceContext"; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java b/weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java index 9906a29bd..9fb4b451e 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java @@ -19,6 +19,7 @@ import java.util.List; import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.Unknown; import org.aspectj.apache.bcel.generic.ConstantPoolGen; +import org.aspectj.bridge.IMessageHandler; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.ISourceContext; @@ -27,7 +28,7 @@ import org.aspectj.weaver.ISourceContext; // bcel to AjAttribute. class BcelAttributes { - public static List readAjAttributes(Attribute[] as, ISourceContext context) { + public static List readAjAttributes(Attribute[] as, ISourceContext context,IMessageHandler msgHandler) { List l = new ArrayList(); for (int i = as.length - 1; i >= 0; i--) { Attribute a = as[i]; @@ -35,7 +36,8 @@ class BcelAttributes { Unknown u = (Unknown) a; String name = u.getName(); if (name.startsWith(AjAttribute.AttributePrefix)) { - l.add(AjAttribute.read(name, u.getBytes(), context)); + AjAttribute attr = AjAttribute.read(name, u.getBytes(), context,msgHandler); + if (attr!=null) l.add(attr); } } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelField.java b/weaver/src/org/aspectj/weaver/bcel/BcelField.java index 14f7367e2..972571b77 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelField.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelField.java @@ -47,7 +47,7 @@ final class BcelField extends ResolvedMember { private void unpackAttributes(World world) { Attribute[] attrs = field.getAttributes(); - List as = BcelAttributes.readAjAttributes(attrs, getSourceContext(world)); + List as = BcelAttributes.readAjAttributes(attrs, getSourceContext(world),world.getMessageHandler()); for (Iterator iter = as.iterator(); iter.hasNext();) { AjAttribute a = (AjAttribute) iter.next(); if (a instanceof AjAttribute.AjSynthetic) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index 202982d76..cf15b093e 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -81,7 +81,7 @@ final class BcelMethod extends ResolvedMember { } private void unpackAjAttributes(World world) { - List as = BcelAttributes.readAjAttributes(method.getAttributes(), getSourceContext(world)); + List as = BcelAttributes.readAjAttributes(method.getAttributes(), getSourceContext(world),world.getMessageHandler()); //System.out.println("unpack: " + this + ", " + as); for (Iterator iter = as.iterator(); iter.hasNext();) { AjAttribute a = (AjAttribute) iter.next(); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index edc5bbe9a..0b4bd9c7c 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -50,6 +50,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { private ResolvedPointcutDefinition[] pointcuts = null; private PerClause perClause = null; private WeaverStateInfo weaverState = null; + private AjAttribute.WeaverVersionInfo wvInfo = null; private List typeMungers = Collections.EMPTY_LIST; private List declares = Collections.EMPTY_LIST; private ResolvedMember[] privilegedAccess = null; @@ -163,7 +164,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { List pointcuts = new ArrayList(); typeMungers = new ArrayList(); declares = new ArrayList(); - List l = BcelAttributes.readAjAttributes(javaClass.getAttributes(), getResolvedTypeX().getSourceContext()); + List l = BcelAttributes.readAjAttributes(javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler()); for (Iterator iter = l.iterator(); iter.hasNext();) { AjAttribute a = (AjAttribute) iter.next(); //System.err.println("unpacking: " + this + " and " + a); @@ -183,6 +184,15 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { if (getResolvedTypeX().getSourceContext() instanceof BcelSourceContext) { ((BcelSourceContext)getResolvedTypeX().getSourceContext()).addAttributeInfo((AjAttribute.SourceContextAttribute)a); } + } else if (a instanceof AjAttribute.WeaverVersionInfo) { + wvInfo = (AjAttribute.WeaverVersionInfo)a; + if (wvInfo.getMajorVersion() > wvInfo.getCurrentWeaverMajorVersion()) { + // The class file containing this attribute was created by a version of AspectJ that + // added some behavior that 'this' version of AspectJ doesn't understand. And the + // class file contains changes that mean 'this' version of AspectJ cannot continue. + throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+ + wvInfo.toCurrentVersionString()+" but the class "+ javaClass.getClassName()+" is version "+wvInfo.toString()); + } } else { throw new BCException("bad attribute " + a); } @@ -279,6 +289,10 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { public ISourceLocation getSourceLocation() { return getResolvedTypeX().getSourceContext().makeSourceLocation(0); //FIXME, we can do better than this } + + public AjAttribute.WeaverVersionInfo getWeaverVersionAttribute() { + return wvInfo; + } public void addParent(ResolvedTypeX newParent) { if (newParent.isClass()) { diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index 285a0a77e..4e105fb0c 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -395,7 +395,11 @@ public final class LazyClassGen { ); return; } - if (myType != null && myType.getWeaverState() != null) { + + // Add a weaver version attribute to the file being produced + myGen.addAttribute(BcelAttributes.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPoolGen())); + + if (myType != null && myType.getWeaverState() != null) { myGen.addAttribute(BcelAttributes.bcelAttribute( new AjAttribute.WeaverState(myType.getWeaverState()), getConstantPoolGen())); diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index 47076f351..fac4f8eab 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -439,7 +439,7 @@ public final class LazyMethodGen { if (enclosingClass != null && enclosingClass.getType() != null) { context = enclosingClass.getType().getSourceContext(); } - List as = BcelAttributes.readAjAttributes(attributes, context); + List as = BcelAttributes.readAjAttributes(attributes, context,null); if (! as.isEmpty()) { out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger... } |