Bug 173694 - Inlined around advice causing NPE in LTW
Summary: Inlined around advice causing NPE in LTW
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: LTWeaving (show other bugs)
Version: 1.5.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.6.1   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-02-09 15:58 EST by Craig Ching CLA
Modified: 2008-06-12 15:54 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Craig Ching CLA 2007-02-09 15:58:08 EST
Using around advice in an aop.xml-specified concreate aspect is causing a NullPointerException.  Specifying -XnoInline in the weaver options works around the problem.

Here is an example that shows what I'm doing:

package com.foo.aspects;

import com.foo.test.Request;
import com.foo.test.Response;

public abstract aspect AbstractServletLogger {

    public abstract pointcut loggedGetOperations2 ();
   
    void around () : loggedGetOperations2 () {
        Object [] args = thisJoinPoint.getArgs();
       
        Request request = (Request)args[0];
        Response response = (Response)args[1];
       
        System.out.println("[AbstractServletLoggerTrace, request]: " + request.getRequest ());
        System.out.println("[AbstractServletLoggerTrace, response]: " + response.getResponse());
       
        proceed ();
    }
}


Here is the aop.xml:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <concrete-aspect name=" com.foo.aspects.ServletLoggerInstance"
            extends="com.foo.aspects.AbstractServletLogger">
            <pointcut name="loggedGetOperations2"
                expression="execution (void com.foo.test.TraceTest.doGet(com.foo.test.Request, com.foo.test.Response))" />
        </concrete-aspect>
    </aspects>
    <weaver options="-verbose -debug">
        <dump within=" com.foo.test.*"/>
    </weaver>
</aspectj>

Here is the main set of code which I'm instrumenting:

package com.foo.test;

public class TraceTest {
   
    public void doGet (Request request, Response response) {
        System.out.println ("Request: " + request.getRequest() + ", Response: " + response.getResponse());
    }

    public static void main(String[] args) {
       
        Request request = new Request ("This is the request");
        Response response = new Response ("This is the response");
        TraceTest t = new TraceTest ();
        t.doGet(request, response);
    }

}

// Simulates the HttpServletRequest class
package com.foo.test;

public class Request {
   
    private String request;
   
    public Request (String request) {
        this.request = request;
    }
   
    public String getRequest () {
        return this.request;
    }

}

// Simulates the HttpServletResponse class
package com.foo.test;

public class Response {

    private String response;
   
    public Response (String response) {
        this.response = response;
    }
   
    public String getResponse () {
        return this.response;
    }

}

And here is what I'm getting:

[AppClassLoader@92e78c] info AspectJ Weaver Version 1.5.3 built on Wednesday Nov 22, 2006 at 11:18:15 GMT
[AppClassLoader@92e78c ] info register classloader sun.misc.Launcher$AppClassLoader@92e78c
[AppClassLoader@92e78c] info using configuration /C:/dev/workspace/AOPTest/bin/META-INF/aop.xml
[AppClassLoader@92e78c] info define aspect com.foo.aspects.ServletLoggerInstance
[AppClassLoader@92e78c] debug weaving 'com.foo.aspects.ServletLoggerInstance'
[AppClassLoader@92e78c] debug generating class 'com.foo.aspects.ServletLoggerInstance'
[AppClassLoader@92e78c] debug weaving ' com.foo.test.TraceTest'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.Factory'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.SourceLocation'
[AppClassLoader@92e78c ] debug cannot weave 'org.aspectj.runtime.reflect.MethodSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.MethodSignature'
[AppClassLoader@92e78c] debug cannot weave ' org.aspectj.runtime.reflect.CodeSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.MemberSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.SignatureImpl '
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.ConstructorSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.ConstructorSignature'
[ AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.UnlockSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.UnlockSignature'
[AppClassLoader@92e78c ] debug cannot weave 'org.aspectj.runtime.reflect.LockSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.LockSignature'
[AppClassLoader@92e78c] debug cannot weave ' org.aspectj.runtime.reflect.AdviceSignatureImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.AdviceSignature'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.CatchClauseSignatureImpl '
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.CatchClauseSignature'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.FieldSignatureImpl'
[AbstractServletLoggerTrace, request]: This is the request
[AbstractServletLoggerTrace, response]: This is the response
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.FieldSignature'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.InitializerSignatureImpl '
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.lang.reflect.InitializerSignature'
[AppClassLoader@92e78c] debug weaving 'com.foo.test.Request'
[AppClassLoader@92e78c] debug weaving ' com.foo.test.Response'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.SignatureImpl$Cache'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.JoinPointImpl$StaticPartImpl '
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.SourceLocationImpl'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.reflect.JoinPointImpl'
[AppClassLoader@92e78c ] debug cannot weave 'org.aspectj.lang.NoAspectBoundException'
[AppClassLoader@92e78c] debug cannot weave 'org.aspectj.runtime.internal.AroundClosure'
Exception in thread "main" java.lang.NullPointerException
    at com.foo.aspects.AbstractServletLogger.ajc$around$com_foo_aspects_AbstractServletLogger$1$c8fd8333proceed(AbstractServletLogger.aj:1)
    at com.foo.test.TraceTest.doGet_aroundBody1$advice(TraceTest.java:119)
    at com.foo.test.TraceTest.doGet(TraceTest.java:1)
    at com.foo.test.TraceTest.main(TraceTest.java:21)

When I do the same thing but put the pointcut in the aspect (and change it from an abstract aspect to a concrete aspect in the code), it works fine, e.g. here is an example of the concrete aspect code:

package com.foo.aspects;

import com.foo.test.Request;
import com.foo.test.Response;

public aspect ServletLogger {

    public pointcut loggedGetOperations2 () : execution (void com.foo.test.TraceTest.doGet(Request, Response));
  
    void around () : loggedGetOperations2 () {
        Object [] args = thisJoinPoint.getArgs();
       
        Request request = (Request)args[0];
        Response response = (Response)args[1];
       
        System.out.println("[Trace, request]: " + request.getRequest ());
        System.out.println("[Trace, response]: " + response.getResponse ());

        proceed ();
    }
}

Decompiling the TraceTest class using JAD from the LTW example (using the dump element) shows me this:

    private static final void doGet_aroundBody1$advice(AbstractServletLogger this, AroundClosure ajc_aroundClosure, JoinPoint thisJoinPoint, Object args[], Request request, Response response, JoinPoint joinpoint)
    {
        Object aobj[] = joinpoint.getArgs();
        Request request1 = (Request)aobj[0];
        Response response1 = (Response)aobj[1];
        System.out.println("[Trace, request]: " + request1.getRequest());
        System.out.println("[Trace, response]: " + response1.getResponse());
        AbstractServletLogger.ajc$around$com_foo_aspects_AbstractServletLogger$1$c8fd8333proceed(response);
    }

I would think that the last line should have a proceed with a Request and a Response arguement.
Comment 1 Andrew Clement CLA 2007-10-26 06:27:03 EDT
take a look for 1.5.4
Comment 2 Andrew Clement CLA 2008-06-12 15:54:37 EDT
I thought I recognized the symptoms when I just read this bug, and so I've just recreated the failure on 1.5.3 and confirmed it is now fixed in 1.6.1.  I think it is related to mixing the aspect types - code style base aspect and annotation style sub aspect (xml defined aspects become annotation style aspects)