More testcases for overweaving and better handling of WeaverStateInfo to avoid the dreaded problems deserialized the 'special key' used to store diffs. With these changes once a class is woven via overweaving we switch the diff we store in the weaverstateinfo to 0 byte array (indicating overweaving happened for later weavers that see it). We also stop writing the special 'key' into the attribute and avoid looking-for and attempting to replace it at the end of weaving.tags/V1_9_3RC1
/******************************************************************************* | /******************************************************************************* | ||||
* Copyright (c) 2004 IBM Corporation and others. | |||||
* Copyright (c) 2004-2019 Contributors | |||||
* All rights reserved. This program and the accompanying materials | * All rights reserved. This program and the accompanying materials | ||||
* are made available under the terms of the Eclipse Public License v1.0 | * are made available under the terms of the Eclipse Public License v1.0 | ||||
* which accompanies this distribution, and is available at | * which accompanies this distribution, and is available at | ||||
* http://www.eclipse.org/legal/epl-v10.html | * http://www.eclipse.org/legal/epl-v10.html | ||||
* | |||||
* Contributors: | |||||
* IBM Corporation - initial API and implementation | |||||
*******************************************************************************/ | *******************************************************************************/ | ||||
package org.aspectj.weaver; | package org.aspectj.weaver; | ||||
import java.text.MessageFormat; | import java.text.MessageFormat; | ||||
import java.util.ResourceBundle; | import java.util.ResourceBundle; | ||||
/** | |||||
* @author Andy Clement | |||||
* @author IBM | |||||
*/ | |||||
public class WeaverMessages { | public class WeaverMessages { | ||||
private static ResourceBundle bundle = ResourceBundle.getBundle("org.aspectj.weaver.weaver-messages"); | private static ResourceBundle bundle = ResourceBundle.getBundle("org.aspectj.weaver.weaver-messages"); | ||||
public static final String HAS_MEMBER_NOT_ENABLED = "hasMemberNotEnabled"; | public static final String HAS_MEMBER_NOT_ENABLED = "hasMemberNotEnabled"; | ||||
public static final String MUST_KEEP_OVERWEAVING_ONCE_START = "mustKeepOverweavingOnceStart"; | |||||
// @AspectJ | // @AspectJ | ||||
public static final String RETURNING_FORMAL_NOT_DECLARED_IN_ADVICE = "returningFormalNotDeclaredInAdvice"; | public static final String RETURNING_FORMAL_NOT_DECLARED_IN_ADVICE = "returningFormalNotDeclaredInAdvice"; | ||||
public static final String THROWN_FORMAL_NOT_DECLARED_IN_ADVICE = "thrownFormalNotDeclaredInAdvice"; | public static final String THROWN_FORMAL_NOT_DECLARED_IN_ADVICE = "thrownFormalNotDeclaredInAdvice"; |
/* ******************************************************************* | /* ******************************************************************* | ||||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||||
* Copyright (c) 2002-2019 Palo Alto Research Center, Incorporated (PARC). | |||||
* All rights reserved. | * All rights reserved. | ||||
* This program and the accompanying materials are made available | * This program and the accompanying materials are made available | ||||
* under the terms of the Eclipse Public License v1.0 | * under the terms of the Eclipse Public License v1.0 | ||||
* themselves If we are reweavable then we also have: Short: Number of aspects that touched this type in some way when it was | * themselves If we are reweavable then we also have: Short: Number of aspects that touched this type in some way when it was | ||||
* previously woven <String> The fully qualified name of each type Int: Length of class file data (i.e. the unwovenclassfile) | * previously woven <String> The fully qualified name of each type Int: Length of class file data (i.e. the unwovenclassfile) | ||||
* Byte[]: The class file data, compressed if REWEAVABLE_COMPRESSION_BIT set. | * Byte[]: The class file data, compressed if REWEAVABLE_COMPRESSION_BIT set. | ||||
* | |||||
* @author Andy Clement | |||||
*/ | */ | ||||
public class WeaverStateInfo { | public class WeaverStateInfo { | ||||
private List<Entry> typeMungers; | private List<Entry> typeMungers; | ||||
} | } | ||||
} | } | ||||
private final static byte[] NO_BYTES = new byte[0]; | |||||
/** | |||||
* If the weaver is ever invoked in over weaving mode, we should | |||||
* not include the key when writing out, it won't be replaced later. | |||||
* If we turn off the reweaving flag that unfortunately removes | |||||
* the 'what aspects have been woven into this type' list which we | |||||
* want to keep as it helps overweaving avoid weaving an aspect in | |||||
* twice. | |||||
*/ | |||||
public void markOverweavingInUse() { | |||||
reweavableDiffMode = false; | |||||
unwovenClassFile = NO_BYTES; | |||||
} | |||||
public void addConcreteMunger(ConcreteTypeMunger munger) { | public void addConcreteMunger(ConcreteTypeMunger munger) { | ||||
typeMungers.add(new Entry(munger.getAspectType(), munger.getMunger())); | typeMungers.add(new Entry(munger.getAspectType(), munger.getMunger())); | ||||
} | } | ||||
return oldStyle; | return oldStyle; | ||||
} | } | ||||
public byte[] getUnwovenClassFileData() { | |||||
return unwovenClassFile; | |||||
} | |||||
public byte[] getUnwovenClassFileData(byte wovenClassFile[]) { | public byte[] getUnwovenClassFileData(byte wovenClassFile[]) { | ||||
if (unwovenClassFileIsADiff) { | if (unwovenClassFileIsADiff) { | ||||
unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile); | unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile); | ||||
} | } | ||||
} else { | } else { | ||||
classData = new byte[unwovenClassFileSize]; | 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 (unwovenClassFileSize != 0) { | |||||
int bytesread = s.read(classData); | |||||
if (bytesread != unwovenClassFileSize) { | |||||
throw new IOException("ERROR whilst reading reweavable data, expected " + unwovenClassFileSize | |||||
+ " bytes, only found " + bytesread); | |||||
} | |||||
} | } | ||||
} | } | ||||
noRawTypePointcutReferences=cannot use a raw type reference to refer to a pointcut in a generic type (use a parameterized reference instead) | noRawTypePointcutReferences=cannot use a raw type reference to refer to a pointcut in a generic type (use a parameterized reference instead) | ||||
hasMemberNotEnabled=the type pattern {0} can only be used when the -XhasMember option is set | hasMemberNotEnabled=the type pattern {0} can only be used when the -XhasMember option is set | ||||
mustKeepOverweavingOnceStart=the type {0} was previously subject to overweaving and after that can only be woven again in overweaving mode | |||||
# Java5 features used in pre-Java 5 environment | # Java5 features used in pre-Java 5 environment | ||||
atannotationNeedsJava5=the @annotation pointcut expression is only supported at Java 5 compliance level or above | atannotationNeedsJava5=the @annotation pointcut expression is only supported at Java 5 compliance level or above |
import java.io.File; | import java.io.File; | ||||
import org.aspectj.apache.bcel.classfile.JavaClass; | |||||
import org.aspectj.testing.XMLBasedAjcTestCase; | import org.aspectj.testing.XMLBasedAjcTestCase; | ||||
import org.aspectj.testing.XMLBasedAjcTestCaseForJava10OrLater; | import org.aspectj.testing.XMLBasedAjcTestCaseForJava10OrLater; | ||||
import org.aspectj.weaver.WeaverStateInfo; | |||||
import junit.framework.Test; | import junit.framework.Test; | ||||
*/ | */ | ||||
public class Ajc193Tests extends XMLBasedAjcTestCaseForJava10OrLater { | public class Ajc193Tests extends XMLBasedAjcTestCaseForJava10OrLater { | ||||
public void testComplexOverweaving1() { | |||||
// This is the same code as the other test but overweaving OFF | |||||
runTest("overweaving"); | |||||
} | |||||
public void testComplexOverweaving2() throws Exception { | |||||
// This is the same code as the other test but overweaving ON | |||||
runTest("overweaving 2"); | |||||
// Asserting the weaver state info in the tests that will drive overweaving behaviour: | |||||
// After step 1 of the test, MyAspect will have been applied. | |||||
JavaClass jc = getClassFrom(new File(ajc.getSandboxDirectory(),"ow1.jar"), "Application"); | |||||
WeaverStateInfo wsi = getWeaverStateInfo(jc); | |||||
assertEquals("[LMyAspect;]", wsi.getAspectsAffectingType().toString()); | |||||
assertTrue(wsi.getUnwovenClassFileData().length>0); | |||||
// After overweaving, MyAspect2 should also be getting applied but the unwovenclassfile | |||||
// data has been blanked out - because we can no longer use it, only overweaving is possible | |||||
// once one overweaving step is done | |||||
jc = getClassFrom(ajc.getSandboxDirectory(), "Application"); | |||||
wsi = getWeaverStateInfo(jc); | |||||
assertEquals("[LMyAspect2;, LMyAspect;]", wsi.getAspectsAffectingType().toString()); | |||||
assertEquals(0,wsi.getUnwovenClassFileData().length); | |||||
} | |||||
// Two steps of overweaving | |||||
public void testComplexOverweaving3() throws Exception { | |||||
// This is the same code as the other test but overweaving ON | |||||
runTest("overweaving 3"); | |||||
// Asserting the weaver state info in the tests that will drive overweaving behaviour: | |||||
// After step 1 of the test, MyAspect will have been applied. | |||||
JavaClass jc = getClassFrom(new File(ajc.getSandboxDirectory(),"ow1.jar"), "Application"); | |||||
WeaverStateInfo wsi = getWeaverStateInfo(jc); | |||||
assertEquals("[LMyAspect;]", wsi.getAspectsAffectingType().toString()); | |||||
assertTrue(wsi.getUnwovenClassFileData().length>0); | |||||
// After overweaving, MyAspect2 should also be getting applied but the unwovenclassfile | |||||
// data has been blanked out - because we can no longer use it, only overweaving is possible | |||||
// once one overweaving step is done | |||||
jc = getClassFrom(new File(ajc.getSandboxDirectory(),"ow3.jar"), "Application"); | |||||
wsi = getWeaverStateInfo(jc); | |||||
assertEquals("[LMyAspect2;, LMyAspect;]", wsi.getAspectsAffectingType().toString()); | |||||
assertEquals(0,wsi.getUnwovenClassFileData().length); | |||||
jc = getClassFrom(ajc.getSandboxDirectory(), "Application"); | |||||
wsi = getWeaverStateInfo(jc); | |||||
assertEquals("[LMyAspect3;, LMyAspect2;, LMyAspect;]", wsi.getAspectsAffectingType().toString()); | |||||
assertEquals(0,wsi.getUnwovenClassFileData().length); | |||||
} | |||||
// overweaving then attempt non overweaving - should fail | |||||
public void testComplexOverweaving4() throws Exception { | |||||
// This is the same code as the other test but overweaving ON | |||||
runTest("overweaving 4"); | |||||
// Asserting the weaver state info in the tests that will drive overweaving behaviour: | |||||
// After step 1 of the test, MyAspect will have been applied. | |||||
JavaClass jc = getClassFrom(new File(ajc.getSandboxDirectory(),"ow1.jar"), "Application"); | |||||
WeaverStateInfo wsi = getWeaverStateInfo(jc); | |||||
assertEquals("[LMyAspect;]", wsi.getAspectsAffectingType().toString()); | |||||
assertTrue(wsi.getUnwovenClassFileData().length>0); | |||||
} | |||||
// Altered version of this test from org.aspectj.systemtest.ajc150.Enums for 542682 | // Altered version of this test from org.aspectj.systemtest.ajc150.Enums for 542682 | ||||
public void decpOnEnumNotAllowed_xlints() { | |||||
public void testDecpOnEnumNotAllowed_xlints() { | |||||
runTest("wildcard enum match in itd"); | runTest("wildcard enum match in itd"); | ||||
} | } | ||||
<suite> | <suite> | ||||
<ajc-test dir="bugs193/389678" vm="1.8" title="overweaving"> | |||||
<compile files="OverWeave_1/src/Application.java,OverWeave_1/src/MyAspect.aj" options="-showWeaveInfo -1.8" outjar="ow1.jar"> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
</compile> | |||||
<compile files="OverWeave_2/src/MyAspect2.aj" options="-1.8" outjar="ow2.jar"> | |||||
<message kind="warning" text="advice defined in MyAspect2 has not been applied"/> | |||||
</compile> | |||||
<compile inpath="ow1.jar" aspectpath="ow2.jar" options="-1.8 -showWeaveInfo"> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect' (ow1.jar!MyAspect.class:2(from MyAspect.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect' (ow1.jar!MyAspect.class:2(from MyAspect.aj))"/> | |||||
</compile> | |||||
<run class="Application" classpath="ow2.jar"> | |||||
<stdout> | |||||
<line text="MyAspect -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect2 -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="MyAspect2 -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="Hello world!"/> | |||||
</stdout> | |||||
</run> | |||||
</ajc-test> | |||||
<ajc-test dir="bugs193/389678" vm="1.8" title="overweaving 2"> | |||||
<compile files="OverWeave_1/src/Application.java,OverWeave_1/src/MyAspect.aj" options="-showWeaveInfo -1.8" outjar="ow1.jar"> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
</compile> | |||||
<compile files="OverWeave_2/src/MyAspect2.aj" options="-1.8" outjar="ow2.jar"> | |||||
<message kind="warning" text="advice defined in MyAspect2 has not been applied"/> | |||||
</compile> | |||||
<compile inpath="ow1.jar" aspectpath="ow2.jar" options="-showWeaveInfo -1.8 -Xset:overWeaving=true"> | |||||
<!-- this is a bit unfortunate, basically MyAspect is not being re-applied because of overweaving | |||||
so we get a message that it hasn't been applied. But really it doesn't need to be. --> | |||||
<message kind="warning" text="advice defined in MyAspect has not been applied"/> | |||||
<!-- These two don't come out because we are using overweaving to apply MyAspect2 where MyAspect is already applied. | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect' (ow1.jar!MyAspect.class:2(from MyAspect.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect' (ow1.jar!MyAspect.class:2(from MyAspect.aj))"/> | |||||
--> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
</compile> | |||||
<run class="Application" classpath="ow2.jar"> | |||||
<stdout> | |||||
<!-- notice order change to overweaving usage --> | |||||
<line text="MyAspect2 -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect2 -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="MyAspect -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="Hello world!"/> | |||||
</stdout> | |||||
</run> | |||||
</ajc-test> | |||||
<ajc-test dir="bugs193/389678" vm="1.8" title="overweaving 3"> | |||||
<compile files="OverWeave_1/src/Application.java,OverWeave_1/src/MyAspect.aj" options="-showWeaveInfo -1.8" outjar="ow1.jar"> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
</compile> | |||||
<compile files="OverWeave_2/src/MyAspect2.aj" options="-1.8" outjar="ow2.jar"> | |||||
<message kind="warning" text="advice defined in MyAspect2 has not been applied"/> | |||||
</compile> | |||||
<compile files="OverWeave_4/src/MyAspect3.aj" options="-1.8" outjar="ow4.jar"> | |||||
<message kind="warning" text="advice defined in MyAspect3 has not been applied"/> | |||||
</compile> | |||||
<compile inpath="ow1.jar" aspectpath="ow2.jar" options="-showWeaveInfo -1.8 -Xset:overWeaving=true" outjar="ow3.jar"> | |||||
<!-- this is a bit unfortunate, basically MyAspect is not being re-applied because of overweaving | |||||
so we get a message that it hasn't been applied. But really it doesn't need to be. --> | |||||
<message kind="warning" text="advice defined in MyAspect has not been applied"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
</compile> | |||||
<compile inpath="ow3.jar" aspectpath="ow4.jar" options="-showWeaveInfo -1.8 -Xset:overWeaving=true"> | |||||
<!-- this is a bit unfortunate, basically MyAspect is not being re-applied because of overweaving | |||||
so we get a message that it hasn't been applied. But really it doesn't need to be. --> | |||||
<message kind="warning" text="advice defined in MyAspect has not been applied"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect3' (ow4.jar!MyAspect3.class:2(from MyAspect3.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect3' (ow4.jar!MyAspect3.class:2(from MyAspect3.aj))"/> | |||||
</compile> | |||||
<run class="Application" classpath="ow2.jar"> | |||||
<stdout> | |||||
<line text="MyAspect3 -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect2 -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect -> execution(void Application.main(String[]))"/> | |||||
<line text="MyAspect3 -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="MyAspect2 -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="MyAspect -> execution(void Application.sayHelloTo(String))"/> | |||||
<line text="Hello world!"/> | |||||
</stdout> | |||||
</run> | |||||
</ajc-test> | |||||
<ajc-test dir="bugs193/389678" vm="1.8" title="overweaving 4"> | |||||
<compile files="OverWeave_1/src/Application.java,OverWeave_1/src/MyAspect.aj" options="-showWeaveInfo -1.8" outjar="ow1.jar"> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect' (MyAspect.aj:2)"/> | |||||
</compile> | |||||
<compile files="OverWeave_2/src/MyAspect2.aj" options="-1.8" outjar="ow2.jar"> | |||||
<message kind="warning" text="advice defined in MyAspect2 has not been applied"/> | |||||
</compile> | |||||
<compile files="OverWeave_4/src/MyAspect3.aj" options="-1.8" outjar="ow4.jar"> | |||||
<message kind="warning" text="advice defined in MyAspect3 has not been applied"/> | |||||
</compile> | |||||
<compile inpath="ow1.jar" aspectpath="ow2.jar" options="-showWeaveInfo -1.8 -Xset:overWeaving=true" outjar="ow3.jar"> | |||||
<!-- this is a bit unfortunate, basically MyAspect is not being re-applied because of overweaving | |||||
so we get a message that it hasn't been applied. But really it doesn't need to be. --> | |||||
<message kind="warning" text="advice defined in MyAspect has not been applied"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.main(java.lang.String[]))' in Type 'Application' (Application.java:2) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
<message kind="weave" text="Join point 'method-execution(void Application.sayHelloTo(java.lang.String))' in Type 'Application' (Application.java:6) advised by before advice from 'MyAspect2' (ow2.jar!MyAspect2.class:2(from MyAspect2.aj))"/> | |||||
</compile> | |||||
<compile inpath="ow3.jar" aspectpath="ow4.jar:ow2.jar" options="-1.8"> | |||||
<message kind="error" text="the type Application was previously subject to overweaving and after that can only be woven again in overweaving mode"/> | |||||
<message kind="error" text="the type MyAspect was previously subject to overweaving and after that can only be woven again in overweaving mode"/> | |||||
</compile> | |||||
</ajc-test> | |||||
<ajc-test dir="bugs193/542682" vm="1.5" title="wildcard enum match in itd"> | <ajc-test dir="bugs193/542682" vm="1.5" title="wildcard enum match in itd"> | ||||
<compile files="SimpleEnum.java,SimpleEnum2.java,EnumAspect04.aj" options="-1.5"> | <compile files="SimpleEnum.java,SimpleEnum2.java,EnumAspect04.aj" options="-1.5"> | ||||
<message kind="warning" line="8" text="enum type SimpleEnum2 matches a declare parents type pattern but is being ignored"/> | <message kind="warning" line="8" text="enum type SimpleEnum2 matches a declare parents type pattern but is being ignored"/> |
if (inReweavableMode) { | if (inReweavableMode) { | ||||
WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(true); | WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(true); | ||||
wsi.addAspectsAffectingType(aspectsAffectingType); | wsi.addAspectsAffectingType(aspectsAffectingType); | ||||
wsi.setUnwovenClassFileData(ty.getJavaClass().getBytes()); | |||||
wsi.setReweavable(true); | |||||
if (!world.isOverWeaving()) { | |||||
wsi.setUnwovenClassFileData(ty.getJavaClass().getBytes()); | |||||
wsi.setReweavable(true); | |||||
} else { | |||||
wsi.markOverweavingInUse(); | |||||
} | |||||
} else { | } else { | ||||
clazz.getOrCreateWeaverStateInfo(false).setReweavable(false); | clazz.getOrCreateWeaverStateInfo(false).setReweavable(false); | ||||
} | } |
if (!alreadyConfirmedReweavableState.contains(requiredTypeSignature)) { | if (!alreadyConfirmedReweavableState.contains(requiredTypeSignature)) { | ||||
ResolvedType rtx = world.resolve(UnresolvedType.forSignature(requiredTypeSignature), true); | ResolvedType rtx = world.resolve(UnresolvedType.forSignature(requiredTypeSignature), true); | ||||
boolean exists = !rtx.isMissing(); | boolean exists = !rtx.isMissing(); | ||||
if (!exists) { | |||||
world.getLint().missingAspectForReweaving.signal(new String[] { rtx.getName(), className }, | |||||
if (!world.isOverWeaving()) { | |||||
if (!exists) { | |||||
world.getLint().missingAspectForReweaving.signal(new String[] { rtx.getName(), className }, | |||||
classType.getSourceLocation(), null); | classType.getSourceLocation(), null); | ||||
// world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.MISSING_REWEAVABLE_TYPE, | |||||
// requiredTypeName, className), classType.getSourceLocation(), null); | |||||
} else { | |||||
if (world.isOverWeaving()) { | |||||
// System.out.println(">> Removing " + requiredTypeName + " from weaving process: " | |||||
// + xcutSet.deleteAspect(rtx)); | |||||
// world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.MISSING_REWEAVABLE_TYPE, | |||||
// requiredTypeName, className), classType.getSourceLocation(), null); | |||||
} else { | } else { | ||||
// weaved in aspect that are not declared in aop.xml | // weaved in aspect that are not declared in aop.xml | ||||
// trigger an error for now | // trigger an error for now | ||||
world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.VERIFIED_REWEAVABLE_TYPE, | world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.VERIFIED_REWEAVABLE_TYPE, | ||||
rtx.getName(), rtx.getSourceLocation().getSourceFile()), null, null); | rtx.getName(), rtx.getSourceLocation().getSourceFile()), null, null); | ||||
} | } | ||||
alreadyConfirmedReweavableState.add(requiredTypeSignature); | |||||
} | } | ||||
alreadyConfirmedReweavableState.add(requiredTypeSignature); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
// ().getFileName(), wsi.getUnwovenClassFileData())); | // ().getFileName(), wsi.getUnwovenClassFileData())); | ||||
// new: reweavable default with clever diff | // new: reweavable default with clever diff | ||||
if (!world.isOverWeaving()) { | if (!world.isOverWeaving()) { | ||||
byte[] bytes = wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes()); | |||||
WeaverVersionInfo wvi = classType.getWeaverVersionAttribute(); | |||||
JavaClass newJavaClass = Utility.makeJavaClass(classType.getJavaClass().getFileName(), bytes); | |||||
classType.setJavaClass(newJavaClass, true); | |||||
classType.getResolvedTypeX().ensureConsistent(); | |||||
byte[] ucfd = wsi.getUnwovenClassFileData(); | |||||
if (ucfd.length == 0) { | |||||
// Size 0 indicates the class was previously overwoven, so you need to be overweaving now! | |||||
world.getMessageHandler().handleMessage( | |||||
MessageUtil.error( | |||||
WeaverMessages.format(WeaverMessages.MUST_KEEP_OVERWEAVING_ONCE_START, | |||||
className))); | |||||
// onType.getName(), annoX.getTypeName(), annoX.getValidTargets()), | |||||
// decA.getSourceLocation())); | |||||
} else { | |||||
byte[] bytes = wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes()); | |||||
JavaClass newJavaClass = Utility.makeJavaClass(classType.getJavaClass().getFileName(), bytes); | |||||
classType.setJavaClass(newJavaClass, true); | |||||
classType.getResolvedTypeX().ensureConsistent(); | |||||
} | |||||
} | } | ||||
// } else { | // } else { | ||||
// classType.resetState(); | // classType.resetState(); |
myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(), getConstantPool())); | myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(), getConstantPool())); | ||||
} | } | ||||
// 352389: don't add another one (there will already be one there and this new one won't deserialize correctly) | |||||
if (!world.isOverWeaving() || !myGen.hasAttribute(WeaverState.AttributeName)) { | |||||
if (myType != null && myType.getWeaverState() != null) { | |||||
// see 389678: TODO more finessing possible here? | |||||
if (world.isOverWeaving()) { | |||||
if (myGen.hasAttribute(WeaverState.AttributeName) && myType!=null && myType.getWeaverState() != null) { | |||||
myGen.removeAttribute(myGen.getAttribute(WeaverState.AttributeName)); | |||||
myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverState(myType.getWeaverState()), getConstantPool())); | |||||
} | |||||
} else { | |||||
if (!myGen.hasAttribute(WeaverState.AttributeName) && myType != null && myType.getWeaverState() != null) { | |||||
myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverState(myType.getWeaverState()), getConstantPool())); | myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverState(myType.getWeaverState()), getConstantPool())); | ||||
} | } | ||||
} | } | ||||
public byte[] getJavaClassBytesIncludingReweavable(BcelWorld world) { | public byte[] getJavaClassBytesIncludingReweavable(BcelWorld world) { | ||||
writeBack(world); | writeBack(world); | ||||
byte[] wovenClassFileData = myGen.getJavaClass().getBytes(); | byte[] wovenClassFileData = myGen.getJavaClass().getBytes(); | ||||
// At 1.6 stackmaps are optional | |||||
// At 1.7 or later stackmaps are required (if not turning off the verifier) | |||||
// At 1.6 stackmaps are optional, whilst at 1.7 and later they | |||||
// are required (unless turning off the verifier) | |||||
if ((myGen.getMajor() == Constants.MAJOR_1_6 && world.shouldGenerateStackMaps()) || myGen.getMajor() > Constants.MAJOR_1_6) { | if ((myGen.getMajor() == Constants.MAJOR_1_6 && world.shouldGenerateStackMaps()) || myGen.getMajor() > Constants.MAJOR_1_6) { | ||||
if (!AsmDetector.isAsmAround) { | if (!AsmDetector.isAsmAround) { | ||||
throw new BCException("Unable to find Asm for stackmap generation (Looking for 'aj.org.objectweb.asm.ClassReader'). Stackmap generation for woven code is required to avoid verify errors on a Java 1.7 or higher runtime"); | throw new BCException("Unable to find Asm for stackmap generation (Looking for 'aj.org.objectweb.asm.ClassReader'). Stackmap generation for woven code is required to avoid verify errors on a Java 1.7 or higher runtime"); | ||||
} | } | ||||
WeaverStateInfo wsi = myType.getWeaverState();// getOrCreateWeaverStateInfo(); | WeaverStateInfo wsi = myType.getWeaverState();// getOrCreateWeaverStateInfo(); | ||||
if (wsi != null && wsi.isReweavable()) { // && !reweavableDataInserted | |||||
if (wsi != null && wsi.isReweavable() && !world.isOverWeaving()) { // && !reweavableDataInserted | |||||
// reweavableDataInserted = true; | // reweavableDataInserted = true; | ||||
return wsi.replaceKeyWithDiff(wovenClassFileData); | return wsi.replaceKeyWithDiff(wovenClassFileData); | ||||
} else { | } else { |