3

Looking at This Eclipse Bug it seems the Java Verifier (since 1.6) has had issues with ApsectJ.

The bug says AspectJ 1.8.1 will fix the problem. But using that with Java8u11 I still get the verify error.

I'm running JUnit4 under STS 3.6.0 (Eclipse 4.4). I believe this configuration is the very latest available of all packages.

Completely replaced the remainder of text with requested example. This seems to be limited to @Around advice. @Before works fine.

JUnit:

package com.test.aspectjdemo.junit;

import static org.junit.Assert.*;
import org.junit.Test;
import com.test.aspectjdemo.domain.AspectTarget;

public class AspectTargetTest {

    @Test
    public void testFirstMethod() throws Throwable {
        AspectTarget aspectTarget = new AspectTarget();
        aspectTarget.firstMethod();
    }
}

Vmarg: -javaagent:C:....m2\repository\org\aspectj\aspectjweaver\1.8.1\aspectjweaver-1.8.1.jar

Class under test (I had some problems because proceed apparently declares it throws Throwable, which makes sense, but this simple test didn't throw anything. So I added a faux exception make it compile :

package com.test.aspectjdemo.domain;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class AspectTarget {

    final Logger logger = LogManager.getLogger();

    int x = 1;

    public void firstMethod() throws Throwable {
        logger.info("Start First Method");
        x = secondMethod(x);
        logger.info("Exit X is {}", x);
    }

    private int secondMethod(int x) throws Throwable {
        logger.info("input is {}", x++);
        if (x==100)
            throw new RuntimeException();
        return new Integer(x);
    }
}

The Aspect:

package com.test.aspectjdemo.aspects;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

public aspect LoggingAspect {

    static final Logger logger = LogManager.getLogger();


    /**
     * Exclude JUnit methods
     */
    @Pointcut("!within(com.test.aspectjdemo.junit..*Test)")
    public void noJunit() {}


    @Pointcut("execution(* com.test.aspectjdemo.domain.*.*(..)) && noJunit()")
    public void allMethods() { }


    @Around("allMethods()")
    public Object allmethods(ProceedingJoinPoint joinPoint) throws Throwable   {

        return joinPoint.proceed();

    }

Finally once again the Error, which is actually thrown when the JUnit attempts to instantiate the AspectTarget (first line of testFirstMethod method).

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    com/test/aspectjdemo/domain/AspectTarget.secondMethod(I)I @23: invokestatic
  Reason:
    Type 'org/aspectj/lang/JoinPoint' (current frame, stack[2]) is not assignable to integer
  Current Frame:
    bci: @23
    flags: { }
    locals: { 'com/test/aspectjdemo/domain/AspectTarget', integer, integer, 'org/aspectj/lang/JoinPoint' }
    stack: { 'com/test/aspectjdemo/domain/AspectTarget', integer, 'org/aspectj/lang/JoinPoint', 'com/test/aspectjdemo/aspects/LoggingAspect', null, 'org/aspectj/lang/JoinPoint' }
  Bytecode:
    0000000: 1b3d b200 4b2a 2a1c b800 51b8 0057 4e2a
    0000010: 1c2d b800 6601 2db8 006a b800 6dac     

    at com.test.aspectjdemo.junit.AspectTargetTest.testFirstMethod(AspectTargetTest.java:13)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Terry
  • 911
  • 10
  • 26
  • Yeah sure, I know what to do next: Please provide a minimal code sample, both Java class and aspect, enabling us to reproduce the problem. – kriegaex Aug 01 '14 at 19:00
  • Yeah I knew better than to not have sample code. And creating the sample I learned that it only affects an @Around joinpoint. It never pays to be lazy. Thanks for your help! – Terry Aug 02 '14 at 13:48

1 Answers1

7

The problem is that you mix native AspectJ syntax (public aspect LoggingAspect) with annotation-style @AspectJ syntax. I can reproduce the problem this way.

Correct @AspectJ syntax:

package com.test.aspectjdemo.aspects;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect {
    @Pointcut("!within(com.test.aspectjdemo.junit..*Test)")
    public void excludeJUnit() {}

    @Pointcut("execution(* com.test.aspectjdemo.domain.*.*(..)) && excludeJUnit()")
    public void allMethods() {}

    @Around("allMethods()")
    public Object allmethods(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        System.out.println(thisJoinPoint);
        return thisJoinPoint.proceed();
    }
}

Correct native AspectJ syntax:

package com.test.aspectjdemo.aspects;

public aspect LoggingAspect {
    pointcut excludeJUnit() :
        !within(com.test.aspectjdemo.junit..*Test);

    pointcut allMethods() :
        execution(* com.test.aspectjdemo.domain.*.*(..)) && excludeJUnit();

    Object around() : allMethods() {
        System.out.println(thisJoinPoint);
        return proceed();
    }
}
kriegaex
  • 63,017
  • 15
  • 111
  • 202