Bug 49638 - exception logging: after() throwing advice can't convert Throwable obj to string and ajc aborts
Summary: exception logging: after() throwing advice can't convert Throwable obj to str...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.1.1   Edit
Hardware: Sun Solaris
: P3 normal (vote)
Target Milestone: 1.2   Edit
Assignee: Jim Hugunin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-07 12:31 EST by Phil Leverton CLA
Modified: 2004-01-09 04:27 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Phil Leverton CLA 2004-01-07 12:31:34 EST
The problem is found by the example in Listing 5.15 from Laddad's AspectJ in
Action book. It looks like an exception object in after() throwing(Throwable ex)
advice has a problem being converted to string in a _logger.logp() call.

Environment
-----------
OS:
Solaris 8 kernel patch level 108528-27 plus j2se recommended patches

Java version:
java -version
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

The problem has also been reproduced with AspectJ 1.1.1 on Windows 2000
5.00.2195, SP 4.

Description
-----------
ajc aborts with the following output:

trouble in: 
public class TestException extends java.lang.Object:
  public static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0
  public static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1
  public void <init>():
                    ALOAD_0     // TestException this   (line 1)
                    INVOKESPECIAL java.lang.Object.<init> ()V
    constructor-execution(void TestException.<init>())
    |               RETURN
    constructor-execution(void TestException.<init>())
  end public void <init>()

  public static void main(String[]):
    method-execution(void TestException.main(java.lang.String[]))
    | method-call(void TestException.perform())
    | | catch java.lang.Throwable -> E0
    | | |           INVOKESTATIC TestException.perform ()V   (line 4)
    | | catch java.lang.Throwable -> E0
    | |             GOTO L0
    | |         E0: ASTORE_1
    | |             INVOKESTATIC ExceptionLoggerAspectV2.aspectOf
()LExceptionLoggerAspectV2;
    | |             ALOAD_1
    | |             GETSTATIC TestException.ajc$tjp_0
Lorg/aspectj/lang/JoinPoint$StaticPart;
    | |             INVOKEVIRTUAL
ExceptionLoggerAspectV2.ajc$after$ExceptionLoggerAspectV2$14a
(Ljava/lang/Throwable;Lorg/aspectj/lang/JoinPoint$StaticPart;)V
    | |             ALOAD_1
    | |             ATHROW
    | |         L0: NOP
    | |             ACONST_NULL
    | |             ASTORE_2
    | |             INVOKESTATIC ExceptionLoggerAspectV2.aspectOf
()LExceptionLoggerAspectV2;
    | |             ALOAD_2
    | |             CHECKCAST java.lang.Throwable
    | |             GETSTATIC TestException.ajc$tjp_0
Lorg/aspectj/lang/JoinPoint$StaticPart;
    | |             INVOKEVIRTUAL
ExceptionLoggerAspectV2.ajc$after$ExceptionLoggerAspectV2$14a
(Ljava/lang/Throwable;Lorg/aspectj/lang/JoinPoint$StaticPart;)V
    | |             NOP
    | method-call(void TestException.perform())
    |               RETURN   (line 5)
    method-execution(void TestException.main(java.lang.String[]))
  end public static void main(String[])

  public static void perform():
    method-execution(void TestException.perform())
    |               ACONST_NULL   (line 8)
    |               ASTORE_0
    |               ALOAD_0     // java.lang.Object nullObj   (line 9)
    | method-call(java.lang.String java.lang.Object.toString())
    | | catch java.lang.Throwable -> E0
    | | |           INVOKEVIRTUAL java.lang.Object.toString ()Ljava/lang/String;
    | | catch java.lang.Throwable -> E0
    | |             GOTO L0
    | |         E0: ASTORE_1
    | |             INVOKESTATIC ExceptionLoggerAspectV2.aspectOf
()LExceptionLoggerAspectV2;
    | |             ALOAD_1
    | |             GETSTATIC TestException.ajc$tjp_1
Lorg/aspectj/lang/JoinPoint$StaticPart;
    | |             INVOKEVIRTUAL
ExceptionLoggerAspectV2.ajc$after$ExceptionLoggerAspectV2$14a
(Ljava/lang/Throwable;Lorg/aspectj/lang/JoinPoint$StaticPart;)V
    | |             ALOAD_1
    | |             ATHROW
    | |         L0: NOP
    | method-call(java.lang.String java.lang.Object.toString())
    |               POP
    |               RETURN   (line 10)
    method-execution(void TestException.perform())
  end public static void perform()
end public class TestException
ABORT
Exception thrown from AspectJ 1.1.1

This might be logged as a bug already -- find current bugs at
  http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler

Bugs for exceptions thrown have titles File:line from the top stack, 
e.g., "SomeFile.java:243"

If you don't find the exception below in a bug, please add a new bug
at http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ
To make the bug a priority, please include a test program
that can reproduce this exception.
can't convert from java.lang.String to java.lang.Throwable
can't convert from java.lang.String to java.lang.Throwable
org.aspectj.weaver.BCException: can't convert from java.lang.String to
java.lang.Throwable
        at org.aspectj.weaver.bcel.Utility.appendConversion(Utility.java:203)
        at org.aspectj.weaver.bcel.BcelVar.appendLoadAndConvert(BcelVar.java:57)
        at org.aspectj.weaver.bcel.BcelAdvice.getAdviceArgSetup(BcelAdvice.java:287)
        at
org.aspectj.weaver.bcel.BcelAdvice.getAdviceInstructions(BcelAdvice.java:244)
        at
org.aspectj.weaver.bcel.BcelShadow.weaveAfterReturning(BcelShadow.java:986)
        at org.aspectj.weaver.bcel.BcelShadow.weaveAfter(BcelShadow.java:941)
        at org.aspectj.weaver.bcel.BcelAdvice.implementOn(BcelAdvice.java:126)
        at org.aspectj.weaver.Shadow.implementMungers(Shadow.java:341)
        at org.aspectj.weaver.Shadow.implement(Shadow.java:313)
        at
org.aspectj.weaver.bcel.BcelClassWeaver.implement(BcelClassWeaver.java:1006)
        at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:299)
        at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:77)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:417)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:390)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:327)
        at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.weaveAndGenerateClassFiles(AjBuildManager.java:256)
        at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:156)
        at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:70)
        at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:99)
        at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:53)
        at org.aspectj.tools.ajc.Main.run(Main.java:217)
        at org.aspectj.tools.ajc.Main.runMain(Main.java:155)
        at org.aspectj.tools.ajc.Main.main(Main.java:72)


1 fail|abort

Sample code is two files, TextException.java and ExceptionLoggerAspectV2.java
(see below). To reproduce the problem, do

$ ajc *.java

File 1  - TestException.java
----------------------------
public class TestException 
{
    public static void main(String[] args) {
        perform();
    }

    public static void perform() {
        Object nullObj = null;
        nullObj.toString();
    }
}

File 2 - ExceptionLoggerAspectV2.java
-------------------------------------
import java.util.logging.*;
import org.aspectj.lang.*;

public aspect ExceptionLoggerAspectV2 
{
    Logger _logger = Logger.getLogger("exceptions");

    ExceptionLoggerAspectV2() {
        _logger.setLevel(Level.ALL);
    }

    pointcut exceptionLogMethods()
        : call(* *.*(..)) && !within(ExceptionLoggerAspectV2);

    after() thowing(Throwable ex) : exceptionLogMethods() {
        if (_logger.isLoggable(Level.WARNING)) {
            Signature sig = thisJoinPointStaticPart.getSignature();
            _logger.logp(Level.WARNING,
                         sig.getDeclaringType().getName(),
                         sig.getName(),
                         "Exception logger aspect", ex);
        }
    }
}
Comment 1 Matthew Webster CLA 2004-01-08 10:18:30 EST
The reason for the compiler failure is a transcription error in the program:

    after() thowing(Throwable ex) : exceptionLogMethods() {

should be

    after() throwing(Throwable ex) : exceptionLogMethods() {

(there is an 'r' missing int throwing). However the compiler should issue a 
syntax error rather than aborting.

Comment 2 Jim Hugunin CLA 2004-01-09 04:27:04 EST
Fixed to produce nice parser error message based on patch from Matthew Webster.