AspectJ и Java8 - неверный тип в стеке операндов

Глядя на эту ошибку Eclipse, кажется, что Java Verifier (начиная с версии 1.6) были проблемы с ApsectJ.

Ошибка говорит, что AspectJ 1.8.1 решит проблему. Но используя это с Java8u11, я все равно получаю ошибку проверки.

Я использую JUnit4 под STS 3.6.0 (Eclipse 4.4). Я считаю, что эта конфигурация является самой последней доступной из всех пакетов.

Полностью заменен оставшийся текст запрошенным примером. Кажется, это ограничивается советом @Around. @Before работает нормально.

Юнит:

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

Тестируемый класс (у меня были некоторые проблемы, потому что continue, по-видимому, объявляет, что он выдает Throwable, что имеет смысл, но этот простой тест ничего не выдал. Поэтому я добавил искусственное исключение, чтобы оно скомпилировалось:

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);
    }
}

Аспект:

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();

    }

Наконец, еще раз ошибка, которая фактически возникает, когда JUnit пытается создать экземпляр AspectTarget (первая строка метода testFirstMethod).

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)

person Terry    schedule 30.07.2014    source источник
comment
Да, конечно, я знаю, что делать дальше: пожалуйста, предоставьте минимальный пример кода, как класса Java, так и аспекта, что позволит нам воспроизвести проблему.   -  person kriegaex    schedule 01.08.2014
comment
Да, я знал лучше, чем не иметь образца кода. И, создавая образец, я узнал, что он влияет только на точку соединения @Around. Никогда не стоит быть ленивым. Спасибо за вашу помощь!   -  person Terry    schedule 02.08.2014


Ответы (1)


Проблема в том, что вы смешиваете собственный синтаксис AspectJ (public aspect LoggingAspect) с синтаксисом @AspectJ в стиле аннотаций. Я могу воспроизвести проблему таким образом.

Правильный синтаксис @AspectJ:

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();
    }
}

Правильный собственный синтаксис AspectJ:

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();
    }
}
person kriegaex    schedule 02.08.2014
comment
ХМ! Удивительно, что мой способ вообще сработал. Большое спасибо! - person Terry; 02.08.2014