]> source.dussan.org Git - aspectj.git/commitdiff
Fix for Bugzilla Bug 44587
authorjhugunin <jhugunin>
Wed, 14 Jan 2004 15:24:06 +0000 (15:24 +0000)
committerjhugunin <jhugunin>
Wed, 14 Jan 2004 15:24:06 +0000 (15:24 +0000)
   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.

12 files changed:
lib/test/aspectjrt.jar
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectClinit.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
runtime/src/org/aspectj/lang/NoAspectBoundException.java
runtime/testsrc/RuntimeModuleTests.java
tests/ajcTests.xml
tests/bugs/ErroneousExceptionConversion.java [new file with mode: 0644]
tests/bugs/ErroneousExceptionConversion1.java [new file with mode: 0644]
tests/new/ConstructorExecInitFails.java
weaver/src/org/aspectj/weaver/AjcMemberMaker.java
weaver/src/org/aspectj/weaver/NameMangler.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java

index 63c73ca1a07757a48b2402ce7d7b62151a7ad17c..7e4e30f0fd891d8cd2a206483539167aa71828dc 100644 (file)
Binary files a/lib/test/aspectjrt.jar and b/lib/test/aspectjrt.jar differ
index 653f3d53716437c403799fbf31640c98befebf19..ebead22ebe1a5205880abbaa6e7ee12e0996d375 100644 (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();
+               }
+               
        }
 
 }
index 6fd3dd5f3975418be4db5b1d2b26c09e950b5cfc..a823f10b047ea9571167e8c8806a080cbdc07aae 100644 (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
index 4bebcfb47e9daac9f8e806298bbdec85c7376ad0..b21d3895c9d0a6f25b84e5676b9203f57000847d 100644 (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; }
+       
 }
index fe36f3055ffaad2d200589cd86ddad5fb34bbfa7..a426025c5bf4a5ce475c12135622d6dd4c60f390 100644 (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());
+    }
 }  
index 6a68bc4a66241e613db57b09c57df955a6c5cf39..e07ae9507b48a18a2c3cae714f23b5bf38939498 100644 (file)
         <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>
diff --git a/tests/bugs/ErroneousExceptionConversion.java b/tests/bugs/ErroneousExceptionConversion.java
new file mode 100644 (file)
index 0000000..13db17a
--- /dev/null
@@ -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");
+       }
+       
+}
+
diff --git a/tests/bugs/ErroneousExceptionConversion1.java b/tests/bugs/ErroneousExceptionConversion1.java
new file mode 100644 (file)
index 0000000..9a8f0e2
--- /dev/null
@@ -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
+               }
+               
+       }
+}
index 4b5e775e4b1ca13cf7272f329524acd4fecc402c..e042f10ff5137011609933b8941d37139cc93432 100644 (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");
index d91d5f65c4b3df13e08d72fcce3a5a8b6a47611c..52d6d614483da0eb9a009c74ef1bc41bd1836383 100644 (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;
index d620ecad804a1e309ce63d3da3f96e849d6657fd..7db5107ce6622d0b413f975c25105650092fc265 100644 (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");
        }
index fde2d9d0ed830eb19233ac51d18f4837b77f9850..8ef653f87fb62c95012588316414df5da64b7767 100644 (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.