Browse Source

Fix for Bugzilla Bug 44587

   Erroneous exception conversion 
and Bugzilla Bug 34206  
   before():execution(new(..)) does not throw NoAspectBoundException 

All exceptions that occur during the static intialization of a persingleton
aspect will be swallowed.  When using that aspect (via aspectOf()) 
a NoAspectBoundException will be thrown with the original exception
from the staitc initializer as the cause.
tags/v_preCompileLoopAlteration
jhugunin 20 years ago
parent
commit
5834de9783

BIN
lib/test/aspectjrt.jar View File


+ 22
- 1
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectClinit.java View File

@@ -18,12 +18,16 @@ import org.aspectj.weaver.AjcMemberMaker;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.Clinit;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
import org.eclipse.jdt.internal.compiler.codegen.Label;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;

public class AspectClinit extends Clinit {
private boolean hasPre, hasPost;
private FieldBinding initFailureField;
public AspectClinit(Clinit old, CompilationResult compilationResult, boolean hasPre, boolean hasPost) {
public AspectClinit(Clinit old, CompilationResult compilationResult, boolean hasPre, boolean hasPost, FieldBinding initFailureField) {
super(compilationResult);
this.needFreeReturn = old.needFreeReturn;
this.sourceEnd = old.sourceEnd;
@@ -33,12 +37,19 @@ public class AspectClinit extends Clinit {
this.hasPre = hasPre;
this.hasPost = hasPost;
this.initFailureField = initFailureField;
}
private ExceptionLabel handlerLabel;

protected void generateSyntheticCode(
ClassScope classScope,
CodeStream codeStream)
{
if (initFailureField != null) {
handlerLabel = new ExceptionLabel(codeStream, classScope.getJavaLangThrowable());
}
if (hasPre) {
final EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);

@@ -64,6 +75,16 @@ public class AspectClinit extends Clinit {
)));
}
if (initFailureField != null) {
handlerLabel.placeEnd();
Label endLabel = new Label(codeStream);
codeStream.goto_(endLabel);
handlerLabel.place();
codeStream.putstatic(initFailureField);
endLabel.place();
}
}

}

+ 11
- 4
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java View File

@@ -151,7 +151,7 @@ public class AspectDeclaration extends TypeDeclaration {
}
}
private FieldBinding initFailureField= null;
public void generateCode(ClassFile enclosingClassFile) {
if (ignoreFurtherInvestigation) {
@@ -170,18 +170,22 @@ public class AspectDeclaration extends TypeDeclaration {
if (!isAbstract()) {
initFailureField = factory.makeFieldBinding(AjcMemberMaker.initFailureCauseField(typeX));
binding.addField(initFailureField);
if (perClause == null) {
// we've already produced an error for this
} else if (perClause.getKind() == PerClause.SINGLETON) {
binding.addField(factory.makeFieldBinding(AjcMemberMaker.perSingletonField(
typeX)));
methods[0] = new AspectClinit((Clinit)methods[0], compilationResult, false, true);
methods[0] = new AspectClinit((Clinit)methods[0], compilationResult, false, true, initFailureField);
} else if (perClause.getKind() == PerClause.PERCFLOW) {
binding.addField(
factory.makeFieldBinding(
AjcMemberMaker.perCflowField(
typeX)));
methods[0] = new AspectClinit((Clinit)methods[0], compilationResult, true, false);
methods[0] = new AspectClinit((Clinit)methods[0], compilationResult, true, false, null);
} else if (perClause.getKind() == PerClause.PEROBJECT) {
// binding.addField(
// world.makeFieldBinding(
@@ -522,10 +526,13 @@ public class AspectDeclaration extends TypeDeclaration {
codeStream.ifnull(isNull);
codeStream.areturn();
isNull.place();
codeStream.new_(world.makeTypeBinding(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION));
codeStream.dup();
codeStream.ldc(typeX.getNameAsIdentifier());
codeStream.getstatic(initFailureField);
codeStream.invokespecial(world.makeMethodBindingForCall(
AjcMemberMaker.noAspectBoundExceptionInit()
AjcMemberMaker.noAspectBoundExceptionInitWithCause()
));
codeStream.athrow();
// body ends here

+ 12
- 0
runtime/src/org/aspectj/lang/NoAspectBoundException.java View File

@@ -18,4 +18,16 @@ package org.aspectj.lang;
* when there is no aspect of that type currently bound.
*/
public class NoAspectBoundException extends RuntimeException {
Throwable cause;
public NoAspectBoundException(String aspectName, Throwable inner) {
super(inner == null ? aspectName :
"Exception while initializing " +aspectName + ": " +inner);
this.cause = inner;
}
public NoAspectBoundException() {
}
public Throwable getCause() { return cause; }
}

+ 8
- 0
runtime/testsrc/RuntimeModuleTests.java View File

@@ -14,6 +14,8 @@

// default package

import org.aspectj.lang.NoAspectBoundException;

import junit.framework.*;

public class RuntimeModuleTests extends TestCase {
@@ -27,4 +29,10 @@ public class RuntimeModuleTests extends TestCase {
public RuntimeModuleTests(String name) { super(name); }

public void testNothing() {}
public void testNoAspectBoundException() {
RuntimeException fun = new RuntimeException("fun");
NoAspectBoundException nab = new NoAspectBoundException("Foo", fun);
assertEquals(fun,nab.getCause());
}
}

+ 14
- 0
tests/ajcTests.xml View File

@@ -7092,4 +7092,18 @@
<run class="Main1"/>
</ajc-test>

<ajc-test dir="bugs" pr="44587"
title="Erroneous exception conversion">
<compile files="ErroneousExceptionConversion.java">
</compile>
<run class="ErroneousExceptionConversion"/>
</ajc-test>
<ajc-test dir="bugs" pr="34206"
title="before():execution(new(..)) does not throw NoAspectBoundException">
<compile files="ErroneousExceptionConversion1.java">
</compile>
<run class="ErroneousExceptionConversion1"/>
</ajc-test>
</suite>

+ 44
- 0
tests/bugs/ErroneousExceptionConversion.java View File

@@ -0,0 +1,44 @@
// pr 44587
import org.aspectj.testing.Tester;
import org.aspectj.lang.NoAspectBoundException;
public class ErroneousExceptionConversion {
public static void main(String[] args) {
try {
new ErroneousExceptionConversion();
Tester.checkFailed("Wanted an exception in initializer error");
} catch (NoAspectBoundException nabEx) {
// good
// check nabEx.getCause instanceof RuntimeException and has explanation "boom..."
Throwable cause = nabEx.getCause();
if (!(cause instanceof RuntimeException)) {
Tester.checkFailed("Should have a RuntimeException as cause");
}
} catch(Throwable t) {
Tester.checkFailed("Wanted an ExceptionInInitializerError but got " + t);
}
}
}

aspect A {
int ErroneousExceptionConversion.someField = throwIt();
public static int throwIt() {
throw new RuntimeException("Exception during aspect initialization");
}
public A() {
System.err.println("boom in 5...");
throw new RuntimeException("boom");
}
// if I change this to execution the test passes...
after() throwing : initialization(ErroneousExceptionConversion.new(..)) {
System.out.println("After throwing");
}
}


+ 26
- 0
tests/bugs/ErroneousExceptionConversion1.java View File

@@ -0,0 +1,26 @@
import org.aspectj.lang.*;
import org.aspectj.testing.Tester;

aspect Watchcall {
pointcut myConstructor(): execution(new(..));

before(): myConstructor() {
System.err.println("Entering Constructor");
}

after(): myConstructor() {
System.err.println("Leaving Constructor");
}
}

public class ErroneousExceptionConversion1 {
public static void main(String[] args) {
try {
ErroneousExceptionConversion1 c = new ErroneousExceptionConversion1();
Tester.checkFailed("shouldn't get here");
} catch (NoAspectBoundException nab) {
// expected
}
}
}

+ 5
- 1
tests/new/ConstructorExecInitFails.java View File

@@ -1,4 +1,5 @@
import org.aspectj.testing.*;
import org.aspectj.lang.*;

/**
* -usejavac mode: no error
@@ -8,7 +9,10 @@ public class ConstructorExecInitFails {
public static void main(String[] args) {
try {
new ConstructorExecInitFails();
} catch (ExceptionInInitializerError e) {
} catch (NoAspectBoundException e) {
Tester.check(e.getCause() instanceof NoAspectBoundException,
"Expected NoAspectBoundException, found " + e.getCause());
return;
}
Tester.checkFailed("shouldn't be able to run");

+ 25
- 5
weaver/src/org/aspectj/weaver/AjcMemberMaker.java View File

@@ -15,6 +15,8 @@ package org.aspectj.weaver;

import java.lang.reflect.Modifier;

import org.aspectj.weaver.ResolvedTypeX.Name;


public class AjcMemberMaker {
private static final int PUBLIC_STATIC_FINAL =
@@ -60,14 +62,23 @@ public class AjcMemberMaker {

public static Member noAspectBoundExceptionInit() {
return new ResolvedMember(
Member.METHOD,
NO_ASPECT_BOUND_EXCEPTION,
Modifier.PUBLIC,
"<init>",
"()V");
Member.METHOD,
NO_ASPECT_BOUND_EXCEPTION,
Modifier.PUBLIC,
"<init>",
"()V");
}

public static Member noAspectBoundExceptionInitWithCause() {
return new ResolvedMember(
Member.METHOD,
NO_ASPECT_BOUND_EXCEPTION,
Modifier.PUBLIC,
"<init>",
"(Ljava/lang/String;Ljava/lang/Throwable;)V");
}

public static ResolvedMember perCflowPush(TypeX declaringType) {
return new ResolvedMember(
Member.METHOD,
@@ -95,6 +106,15 @@ public class AjcMemberMaker {
declaringType.getSignature());
}

public static ResolvedMember initFailureCauseField(TypeX declaringType) {
return new ResolvedMember(
Member.FIELD,
declaringType,
PRIVATE_STATIC,
NameMangler.INITFAILURECAUSE_FIELD_NAME,
TypeX.THROWABLE.getSignature());
}
public static ResolvedMember perObjectField(TypeX declaringType, ResolvedTypeX aspectType) {
int modifiers = Modifier.PRIVATE;

+ 2
- 2
weaver/src/org/aspectj/weaver/NameMangler.java View File

@@ -40,8 +40,8 @@ public class NameMangler {

public static final String AJC_POST_CLINIT_NAME = PREFIX + "postClinit";

public static final String INITFAILURECAUSE_FIELD_NAME = PREFIX + "initFailureCause";
public static String perObjectInterfaceGet(TypeX aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "perObjectGet");
}

+ 18
- 0
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java View File

@@ -904,6 +904,8 @@ class BcelClassWeaver implements IClassWeaver {
// assert t.getHandler() == ih
ExceptionRange er = (ExceptionRange) t;
if (er.getCatchType() == null) continue;
if (isInitFailureHandler(ih)) return;
match(
BcelShadow.makeExceptionHandler(
world,
@@ -915,6 +917,14 @@ class BcelClassWeaver implements IClassWeaver {
}
}

private boolean isInitFailureHandler(InstructionHandle ih) {
if (ih.getInstruction() instanceof PUTSTATIC) {
String name = ((PUTSTATIC)ih.getInstruction()).getFieldName(cpg);
if (name.equals(NameMangler.INITFAILURECAUSE_FIELD_NAME)) return true;
}
return false;
}


private void matchSetInstruction(
LazyMethodGen mg,
@@ -923,6 +933,10 @@ class BcelClassWeaver implements IClassWeaver {
List shadowAccumulator) {
FieldInstruction fi = (FieldInstruction) ih.getInstruction();
Member field = BcelWorld.makeFieldSignature(clazz, fi);
// synthetic fields are never join points
if (field.getName().startsWith(NameMangler.PREFIX)) return;
ResolvedMember resolvedField = field.resolve(world);
if (resolvedField == null) {
// we can't find the field, so it's not a join point.
@@ -946,6 +960,10 @@ class BcelClassWeaver implements IClassWeaver {
private void matchGetInstruction(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) {
FieldInstruction fi = (FieldInstruction) ih.getInstruction();
Member field = BcelWorld.makeFieldSignature(clazz, fi);
// synthetic fields are never join points
if (field.getName().startsWith(NameMangler.PREFIX)) return;
ResolvedMember resolvedField = field.resolve(world);
if (resolvedField == null) {
// we can't find the field, so it's not a join point.

Loading…
Cancel
Save