summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2005-10-05 12:23:52 +0000
committeraclement <aclement>2005-10-05 12:23:52 +0000
commit12e6334bf5f77d7c3bc2e66eeefa105f0507334a (patch)
tree740bd9271abcafb3bad10c01ba3060d8383efce0 /weaver
parent451fea8a2f9b3640d6c133c3f01dad8b9a78f72c (diff)
downloadaspectj-12e6334bf5f77d7c3bc2e66eeefa105f0507334a.tar.gz
aspectj-12e6334bf5f77d7c3bc2e66eeefa105f0507334a.zip
Let the bug floodgates open, reweavable is now default (pr91417)
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/WeaverStateInfo.java302
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java25
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java2
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java15
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java21
-rw-r--r--weaver/src/org/aspectj/weaver/weaver-messages.properties2
6 files changed, 297 insertions, 70 deletions
diff --git a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java
index 53aa6ffed..ca3fe6356 100644
--- a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java
+++ b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java
@@ -13,6 +13,8 @@
package org.aspectj.weaver;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -25,12 +27,10 @@ import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
import org.aspectj.bridge.IMessage;
import org.aspectj.weaver.bcel.BcelTypeMunger;
-
/**
* WeaverStateInfo represents how a type was processed. It is used by the weaver to determine how a type
* was previously treated and whether reweaving is allowed.
@@ -51,31 +51,48 @@ public class WeaverStateInfo {
private List/*Entry*/ typeMungers;
private boolean oldStyle;
-
-
private boolean reweavable;
- private boolean reweavableCompressedMode; // If true, unwovenClassFile is compressed on write and uncompressed on read
+ private boolean reweavableCompressedMode; // If true, unwovenClassFile is uncompressed on read
+ private boolean reweavableDiffMode; // if true, unwovenClassFile is written and read as a diff
+
private Set /*String*/ aspectsAffectingType; // These must exist in the world for reweaving to be valid
private byte[] unwovenClassFile; // Original 'untouched' class file
- private static boolean reweavableDefault = false;
+ private static boolean reweavableDefault = true; // ajh02: changed from false;
private static boolean reweavableCompressedModeDefault = false;
+ private static boolean reweavableDiffModeDefault = true;
+
+ // when serializing the WeaverStateInfo we come to adding the reweavable data,
+ // we'd like to add a diff of the unwovenClassFile and the wovenClassFile,
+ // but we don't have the wovenClassFile yet as we're still in the process of making it.
+ // so we put this key there instead as a stub.
+ // Then when the wovenClassFile has been made, replaceKeyWithDiff is called.
+ private static byte [] key = {
+ -51, 34, 105, 56, -34, 65, 45, 78, -26, 125, 114, 97, 98, 1, -1, -42
+ };
+ private boolean unwovenClassFileIsADiff = false;
public WeaverStateInfo() {
- this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault);
+ this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault,reweavableDiffModeDefault);
}
- private WeaverStateInfo(List typeMungers, boolean oldStyle,boolean reweavableMode,boolean reweavableCompressedMode) {
+ public WeaverStateInfo(boolean reweavable) {
+ this(new ArrayList(), false,reweavable,reweavableCompressedModeDefault,reweavableDiffModeDefault);
+ }
+
+ private WeaverStateInfo(List typeMungers, boolean oldStyle,boolean reweavableMode,boolean reweavableCompressedMode,boolean reweavableDiffMode) {
this.typeMungers = typeMungers;
this.oldStyle = oldStyle;
this.reweavable = reweavableMode;
this.reweavableCompressedMode = reweavableCompressedMode;
+ this.reweavableDiffMode = reweavableMode?reweavableDiffMode:false;
this.aspectsAffectingType= new HashSet();
this.unwovenClassFile = null;
}
- public static void setReweavableModeDefaults(boolean mode, boolean compress) {
+ public static void setReweavableModeDefaults(boolean mode, boolean compress, boolean diff) {
reweavableDefault = mode;
reweavableCompressedModeDefault = compress;
+ reweavableDiffModeDefault = diff;
}
private static final int UNTOUCHED=0, WOVEN=2, EXTENDED=3;
@@ -83,21 +100,32 @@ public class WeaverStateInfo {
// Use 'bits' for these capabilities - only valid in EXTENDED mode
private static final byte REWEAVABLE_BIT = 1<<4;
private static final byte REWEAVABLE_COMPRESSION_BIT = 1<<5;
+ private static final byte REWEAVABLE_DIFF_BIT = 1<<6;
+ /** See comments on write() */
public static final WeaverStateInfo read(VersionedDataInputStream s, ISourceContext context) throws IOException {
byte b = s.readByte();
boolean isReweavable = ((b&REWEAVABLE_BIT)!=0);
- if (isReweavable) b=(byte) (b-REWEAVABLE_BIT);
+ if (isReweavable){
+ b=(byte) (b-REWEAVABLE_BIT);
+ }
boolean isReweavableCompressed = ((b&REWEAVABLE_COMPRESSION_BIT)!=0);
- if (isReweavableCompressed) b=(byte) (b-REWEAVABLE_COMPRESSION_BIT);
+ if (isReweavableCompressed){
+ b=(byte) (b-REWEAVABLE_COMPRESSION_BIT);
+ }
+
+ boolean isReweavableDiff = ((b&REWEAVABLE_DIFF_BIT)!=0);
+ if (isReweavableDiff){
+ b=(byte) (b-REWEAVABLE_DIFF_BIT);
+ }
switch(b) {
case UNTOUCHED:
throw new RuntimeException("unexpected UNWOVEN");
case WOVEN:
- return new WeaverStateInfo(Collections.EMPTY_LIST, true,isReweavable,isReweavableCompressed);
+ return new WeaverStateInfo(Collections.EMPTY_LIST, true,isReweavable,isReweavableCompressed,isReweavableDiff);
case EXTENDED:
int n = s.readShort();
List l = new ArrayList();
@@ -107,7 +135,7 @@ public class WeaverStateInfo {
ResolvedTypeMunger.read(s, context);
l.add(new Entry(aspectType, typeMunger));
}
- WeaverStateInfo wsi = new WeaverStateInfo(l,false,isReweavable,isReweavableCompressed);
+ WeaverStateInfo wsi = new WeaverStateInfo(l,false,isReweavable,isReweavableCompressed,isReweavableDiff);
readAnyReweavableData(wsi,s);
return wsi;
}
@@ -129,13 +157,28 @@ public class WeaverStateInfo {
}
}
+ /**
+ * Serialize the WeaverStateInfo. Various bits are set within the 'kind' flag to indicate the structure of
+ * the attribute. In reweavable diff mode a 'marker' is inserted at the start of the attribute to indicate
+ * where the final calculated diff should be inserted. When the key is replaced with the diff, the 'kind'
+ * byte moves to the front of the attribute - thats why in the read logic you'll see it expecting the
+ * kind as the first byte.
+ */
public void write(DataOutputStream s) throws IOException {
- if (oldStyle) throw new RuntimeException("shouldn't be writing this");
+ if (oldStyle || reweavableCompressedMode) {
+ throw new RuntimeException("shouldn't be writing this");
+ }
byte weaverStateInfoKind = EXTENDED;
if (reweavable) weaverStateInfoKind |= REWEAVABLE_BIT;
- if (reweavableCompressedMode) weaverStateInfoKind |= REWEAVABLE_COMPRESSION_BIT;
+
+ if (reweavableDiffMode){
+ s.write(key); // put key in so we can replace it with the diff later
+ weaverStateInfoKind |= REWEAVABLE_DIFF_BIT;
+ }
+
s.writeByte(weaverStateInfoKind);
+
int n = typeMungers.size();
s.writeShort(n);
for (int i=0; i < n; i++) {
@@ -176,10 +219,14 @@ public class WeaverStateInfo {
public boolean isOldStyle() {
return oldStyle;
}
-
- public byte[] getUnwovenClassFileData() {
+
+ public byte[] getUnwovenClassFileData(byte wovenClassFile[]) {
+ if (unwovenClassFileIsADiff){
+ unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile);
+ unwovenClassFileIsADiff = false;
+ }
return unwovenClassFile;
- }
+ }
public void setUnwovenClassFileData(byte[] data) {
unwovenClassFile = data;
@@ -189,9 +236,8 @@ public class WeaverStateInfo {
return reweavable;
}
- public void setReweavable(boolean rw,boolean compressData) {
+ public void setReweavable(boolean rw) {
reweavable = rw;
- reweavableCompressedMode = compressData;
}
public void addAspectsAffectingType(Collection /*String*/ aspects) {
@@ -204,11 +250,8 @@ public class WeaverStateInfo {
return this.aspectsAffectingType;
}
-
- ////
-
+
private static void readAnyReweavableData(WeaverStateInfo wsi,DataInputStream s) throws IOException {
-
if (wsi.isReweavable()) {
// Load list of aspects that need to exist in the world for reweaving to be 'legal'
int numberAspectsAffectingType = s.readShort();
@@ -216,18 +259,9 @@ public class WeaverStateInfo {
int unwovenClassFileSize = s.readInt();
byte[] classData = null;
- // The data might or might not be compressed:
- if (!wsi.reweavableCompressedMode) {
- // Read it straight in
- classData = new byte[unwovenClassFileSize];
- int bytesread = s.read(classData);
- if (bytesread!=unwovenClassFileSize)
- throw new IOException("ERROR whilst reading reweavable data, expected "+
- unwovenClassFileSize+" bytes, only found "+bytesread);
- } else {
- // Decompress it
- classData = new byte[unwovenClassFileSize];
-
+ // the unwovenClassFile may have been compressed:
+ if (wsi.reweavableCompressedMode) {
+ classData = new byte[unwovenClassFileSize];
ZipInputStream zis = new ZipInputStream(s);
ZipEntry zen = zis.getNextEntry();
int current = 0;
@@ -239,13 +273,191 @@ public class WeaverStateInfo {
}
zis.closeEntry();
if (bytesToGo!=0)
- throw new IOException("ERROR whilst reading compressed reweavable data, expected "+
- unwovenClassFileSize+" bytes, only found "+current);
+ throw new IOException("ERROR whilst reading compressed reweavable data, expected "+
+ unwovenClassFileSize+" bytes, only found "+current);
+ } else {
+ classData = new byte[unwovenClassFileSize];
+ int bytesread = s.read(classData);
+ if (bytesread!=unwovenClassFileSize)
+ throw new IOException("ERROR whilst reading reweavable data, expected "+
+ unwovenClassFileSize+" bytes, only found "+bytesread);
}
+
+ // if it was diffMode we'll have to remember to apply the diff if someone
+ // asks for the unwovenClassFile
+ wsi.unwovenClassFileIsADiff = wsi.reweavableDiffMode;
wsi.setUnwovenClassFileData(classData);
}
}
+ /**
+ * Here is the cleverness for reweavable diff mode. The class file on disk contains, inside the weaverstateinfo attribute, a diff
+ * that can be applied to 'itself' to recover the original class - which can then be rewoven.
+ */
+ public byte[] replaceKeyWithDiff(byte wovenClassFile[]) {
+ // we couldn't have made the diff earlier
+ // as we didn't have the wovenClassFile
+ // so we left a key there as a marker to come back to
+
+ if (reweavableDiffMode){
+ ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
+ DataOutputStream s = new DataOutputStream(arrayStream);
+
+ int endOfKey = findEndOfKey(wovenClassFile);
+ int startOfKey = endOfKey - key.length;
+ // the length of the wsi attribute is written infront of it in the classFile,
+ // swapping the diff for the key will probably change the length of the wsi,
+ // so we'll have to fiddle with the four 'int length' bytes
+ int oldLengthLocation = startOfKey -4;
+ int oldLength = readInt(wovenClassFile, oldLengthLocation);
+ wovenClassFile = deleteInArray(wovenClassFile,startOfKey,endOfKey); // delete the key
+
+ byte [] wovenClassFileUpToWSI = new byte [oldLengthLocation];
+ System.arraycopy(wovenClassFile,0,wovenClassFileUpToWSI,0,oldLengthLocation);
+
+ byte [] diff = generateDiff(wovenClassFileUpToWSI, unwovenClassFile);
+ try { // put the length of the diff infront of the diff
+ s.writeInt(diff.length);
+ s.write(diff);
+ } catch(IOException e){}
+ diff = arrayStream.toByteArray();
+ // we have to swap the oldLength for the new one,
+ // and add the diff, using the oldLength to work out where it should go :)
+
+ int newLength = oldLength - key.length + diff.length;
+ byte newLengthBytes[] = serializeInt(newLength);
+
+ // swap in the serialized newLength for the oldOne:
+ wovenClassFile[oldLengthLocation] = newLengthBytes[0];
+ wovenClassFile[oldLengthLocation + 1] = newLengthBytes[1];
+ wovenClassFile[oldLengthLocation + 2] = newLengthBytes[2];
+ wovenClassFile[oldLengthLocation + 3] = newLengthBytes[3];
+
+ // add the diff
+ wovenClassFile = insertArray(diff, wovenClassFile, oldLengthLocation + 4 + oldLength - key.length);
+ }
+ return wovenClassFile;
+ }
+
+ private static final int findEndOfKey(byte [] wovenClassFile){
+ // looks through the classfile backwards (as the attributes are all near the end)
+ for(int i = wovenClassFile.length - 1; i > 0; i--)
+ if(endOfKeyHere(wovenClassFile, i)){
+ return i + 1;
+ }
+ throw new RuntimeException("key not found in wovenClassFile"); // should never happen
+ }
+
+ private static final boolean endOfKeyHere(byte lookIn[], int i){
+ for(int j = 0; j < key.length; j++)
+ if(key[key.length - 1 - j] != lookIn[i - j]){
+ return false;
+ }
+ return true;
+ }
+ private static final byte[] insertArray(byte toInsert[], byte original[], int offset){
+ byte result[] = new byte[original.length + toInsert.length];
+ System.arraycopy(original, 0, result, 0, offset);
+ System.arraycopy(toInsert, 0, result, offset, toInsert.length);
+ System.arraycopy(original, offset, result, offset + toInsert.length, original.length - offset);
+ return result;
+ }
+ private static final int readInt(byte [] a, int offset){
+ ByteArrayInputStream b = new ByteArrayInputStream(a, offset, 4);
+ DataInputStream d = new DataInputStream(b);
+ int length = -1;
+ try{
+ length = d.readInt();
+ }
+ catch(IOException e) {
+ throw(new RuntimeException("readInt called with a bad array or offset")); // should never happen
+ }
+ return length;
+ }
+ private static final byte[] deleteInArray(byte a[], int start, int end){
+ int lengthToDelete = end - start;
+ byte result[] = new byte[a.length - lengthToDelete]; // make a new array
+ System.arraycopy(a, 0, result, 0, start); // copy in the bit before the deleted bit
+ System.arraycopy(a, end, result, start, a.length - end); // copy in the bit after the deleted bit
+ return result;
+ }
+
+ // ajh02: a quick note about the diff format...
+ //
+ // classfiles consist of:
+ // 8 bytes: magic number and minor and major versions,
+ // 2 bytes: its constant pool count
+ // n bytes: the rest of the class file
+ //
+ // weaving a classfile never changes the classfile's first 8 bytes,
+ // and after the constant pool count there's usually a run of bytes that weaving didn't change
+ // hereafter referred to as the run
+ //
+ // so the diff consists of:
+ // 2 bytes: its constant pool count
+ // 4 bytes: length of the run
+ // n bytes: the rest of the unwovenClassFile
+
+ byte [] generateDiff(byte [] wovenClassFile, byte [] unWovenClassFile){
+
+ // find how long the run is
+ int lookingAt = 10;
+ int shorterLength
+ =(wovenClassFile.length < unWovenClassFile.length)? wovenClassFile.length:unWovenClassFile.length;
+ while (lookingAt < shorterLength && (wovenClassFile[lookingAt] == unWovenClassFile[lookingAt])){
+ lookingAt++;
+ }
+ int lengthInCommon = lookingAt - 10;
+ byte [] diff = new byte [unWovenClassFile.length - 4 - lengthInCommon];
+
+ // first 2 bytes of the diff are the constant pool count
+ diff[0] = unWovenClassFile[8];
+ diff[1] = unWovenClassFile[9];
+
+ // then 4 bytes saying how long the run is
+ byte [] lengthInCommonBytes = serializeInt(lengthInCommon);
+ diff[2] = lengthInCommonBytes[0];
+ diff[3] = lengthInCommonBytes[1];
+ diff[4] = lengthInCommonBytes[2];
+ diff[5] = lengthInCommonBytes[3];
+
+ // then we just dump the rest of the unWovenClassFile verbatim
+ System.arraycopy(unWovenClassFile,10+lengthInCommon,diff,6,diff.length-6);
+
+ return diff;
+ }
+
+ byte [] applyDiff(byte [] wovenClassFile, byte [] diff){
+
+ int lengthInCommon = readInt(diff,2);
+ byte [] unWovenClassFile = new byte [4 + diff.length + lengthInCommon];
+
+ // copy the first 8 bytes from the wovenClassFile
+ System.arraycopy(wovenClassFile,0,unWovenClassFile,0,8);
+
+ // copy the constant pool count from the diff
+ unWovenClassFile[8] = diff[0];
+ unWovenClassFile[9] = diff[1];
+
+ // copy the run from the wovenClassFile
+ System.arraycopy(wovenClassFile,10,unWovenClassFile,10,lengthInCommon);
+
+ // copy the stuff after the run from the diff
+ System.arraycopy(diff,6,unWovenClassFile,10+lengthInCommon,diff.length-6);
+
+ return unWovenClassFile;
+ }
+
+ private byte [] serializeInt(int i){
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(4);
+ DataOutputStream dos = new DataOutputStream(bos);
+ try {
+ dos.writeInt(i);
+ } catch(IOException e) {}
+ return bos.toByteArray();
+ }
+
+
private static void writeAnyReweavableData(WeaverStateInfo wsi,DataOutputStream s) throws IOException {
@@ -259,16 +471,12 @@ public class WeaverStateInfo {
}
}
byte[] data = wsi.unwovenClassFile;
- s.writeInt(data.length);
- // Do we need to compress the data?
- if (!wsi.reweavableCompressedMode) {
+
+ // if we're not in diffMode, write the unwovenClassFile now,
+ // otherwise we'll insert it as a diff later
+ if (!wsi.reweavableDiffMode) {
+ s.writeInt(data.length);
s.write(wsi.unwovenClassFile);
- } else {
- ZipOutputStream zos = new ZipOutputStream(s);
- ZipEntry ze = new ZipEntry("data");
- zos.putNextEntry(ze);
- zos.write(wsi.unwovenClassFile,0,wsi.unwovenClassFile.length);
- zos.closeEntry();
}
}
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
index a6fe494f3..05dc3fd14 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
@@ -120,7 +120,6 @@ class BcelClassWeaver implements IClassWeaver {
// Static setting across BcelClassWeavers
private static boolean inReweavableMode = false;
- private static boolean compressReweavableAttributes = false;
private List addedSuperInitializersAsList = null; // List<IfaceInitList>
@@ -425,17 +424,17 @@ class BcelClassWeaver implements IClassWeaver {
// finally, if we changed, we add in the introduced methods.
if (isChanged) {
- clazz.getOrCreateWeaverStateInfo();
+ clazz.getOrCreateWeaverStateInfo(inReweavableMode);
weaveInAddedMethods(); // FIXME asc are these potentially affected by declare annotation?
}
- if (inReweavableMode || clazz.getType().isAspect()) {
- WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo();
+ if (inReweavableMode) {
+ WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(true);
wsi.addAspectsAffectingType(aspectsAffectingType);
wsi.setUnwovenClassFileData(ty.getJavaClass().getBytes());
- wsi.setReweavable(true,compressReweavableAttributes);
+ wsi.setReweavable(true);
} else {
- clazz.getOrCreateWeaverStateInfo().setReweavable(false,false);
+ clazz.getOrCreateWeaverStateInfo(false).setReweavable(false);
}
return isChanged;
@@ -926,7 +925,9 @@ class BcelClassWeaver implements IClassWeaver {
ShadowMunger aMunger = (ShadowMunger) iter2.next();
if (aMunger instanceof BcelAdvice) {
BcelAdvice bAdvice = (BcelAdvice)aMunger;
- aspectsAffectingType.add(bAdvice.getConcreteAspect().getName());
+ if(bAdvice.getConcreteAspect() != null){
+ aspectsAffectingType.add(bAdvice.getConcreteAspect().getName());
+ }
} else {
// It is a 'Checker' - we don't need to remember aspects that only contributed Checkers...
}
@@ -1769,7 +1770,8 @@ class BcelClassWeaver implements IClassWeaver {
shadow.implement();
CompilationAndWeavingContext.leavingPhase(tok);
}
- mg.matchedShadows = null;
+ int ii = mg.getMaxLocals();
+ mg.matchedShadows = null;
}
// ----
@@ -1787,9 +1789,12 @@ class BcelClassWeaver implements IClassWeaver {
}
// Called by the BcelWeaver to let us know all BcelClassWeavers need to collect reweavable info
- public static void setReweavableMode(boolean mode,boolean compress) {
+ public static void setReweavableMode(boolean mode) {
inReweavableMode = mode;
- compressReweavableAttributes = compress;
+ }
+
+ public static boolean getReweavableMode() {
+ return inReweavableMode;
}
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
index 19cfd39a1..0205d0a08 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
@@ -103,7 +103,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (changed && munger.changesPublicSignature()) {
WeaverStateInfo info =
- weaver.getLazyClassGen().getOrCreateWeaverStateInfo();
+ weaver.getLazyClassGen().getOrCreateWeaverStateInfo(weaver.getReweavableMode());
info.addConcreteMunger(this);
}
// Whilst type mungers aren't persisting their source locations, we add this relationship during
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
index 275094c88..ae688a5ff 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
@@ -1179,7 +1179,10 @@ public class BcelWeaver implements IWeaver {
}
}
}
- classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData()));
+ // old:
+ //classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData()));
+ // new: reweavable default with clever diff
+ classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
} else {
classType.resetState();
}
@@ -1219,7 +1222,7 @@ public class BcelWeaver implements IWeaver {
public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
List childClasses = clazz.getChildClasses(world);
UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];
- ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClass(world).getBytes());
+ ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClassBytesIncludingReweavable(world));
int index = 1;
for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next();
@@ -1552,10 +1555,10 @@ public class BcelWeaver implements IWeaver {
this.progressPerClassFile = progressPerClassFile;
}
- public void setReweavableMode(boolean mode,boolean compress) {
- inReweavableMode = mode;
- WeaverStateInfo.setReweavableModeDefaults(mode,compress);
- BcelClassWeaver.setReweavableMode(mode,compress);
+ public void setReweavableMode(boolean xNotReweavable) {
+ inReweavableMode = !xNotReweavable;
+ WeaverStateInfo.setReweavableModeDefaults(!xNotReweavable,false,true);
+ BcelClassWeaver.setReweavableMode(!xNotReweavable);
}
public boolean isReweavable() {
diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
index ccba01c09..04c88df8e 100644
--- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
+++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
@@ -600,6 +600,18 @@ public final class LazyClassGen {
writeBack(world);
return myGen.getJavaClass();
}
+
+ public byte [] getJavaClassBytesIncludingReweavable(BcelWorld world){
+ writeBack(world);
+ byte [] wovenClassFileData = myGen.getJavaClass().getBytes();
+ WeaverStateInfo wsi = myType.getWeaverState();//getOrCreateWeaverStateInfo();
+ if(wsi != null && wsi.isReweavable()){ // && !reweavableDataInserted
+ //reweavableDataInserted = true;
+ return wsi.replaceKeyWithDiff(wovenClassFileData);
+ } else{
+ return wovenClassFileData;
+ }
+ }
public void addGeneratedInner(LazyClassGen newClass) {
classGens.add(newClass);
@@ -749,7 +761,7 @@ public final class LazyClassGen {
}
public boolean isReweavable() {
- if (myType.getWeaverState()==null) return false;
+ if (myType.getWeaverState()==null) return true;
return myType.getWeaverState().isReweavable();
}
@@ -757,12 +769,11 @@ public final class LazyClassGen {
if (myType.getWeaverState()==null) return null;
return myType.getWeaverState().getAspectsAffectingType();
}
-
- public WeaverStateInfo getOrCreateWeaverStateInfo() {
+
+ public WeaverStateInfo getOrCreateWeaverStateInfo(boolean inReweavableMode) {
WeaverStateInfo ret = myType.getWeaverState();
if (ret != null) return ret;
-
- ret = new WeaverStateInfo();
+ ret = new WeaverStateInfo(inReweavableMode);
myType.setWeaverState(ret);
return ret;
}
diff --git a/weaver/src/org/aspectj/weaver/weaver-messages.properties b/weaver/src/org/aspectj/weaver/weaver-messages.properties
index 533a4374f..9290f3534 100644
--- a/weaver/src/org/aspectj/weaver/weaver-messages.properties
+++ b/weaver/src/org/aspectj/weaver/weaver-messages.properties
@@ -67,7 +67,7 @@ missingPerClause=expected per clause on super aspect not found on {0}
wrongPerClause=wrong kind of per clause on super, expected {0} but found {1}
# Reweavable messages...
-alreadyWoven=class ''{0}'' is already woven and has not been built with -Xreweavable
+alreadyWoven=class ''{0}'' is already woven and has not been built in reweavable mode
reweavableMode=weaver operating in reweavable mode. Need to verify any required types exist.
processingReweavable=processing reweavable type {0}: {1}
missingReweavableType=type {0} is needed by reweavable type {1}