ASTECTJとJAVA8 - オペランドスタックのバッドタイプ
-
21-12-2019 - |
質問
このEclipseのバグそれはJava Verifier(以来) 1.6)APSECTJに関する問題がありました。
バグは、AspectJ 1.8.1が問題を解決すると言っています。しかし、Java8U11でそれを使用しています。まだ検証エラーが発生します。
STS 3.6.0(Eclipse 4.4)でJUNIT4を実行しています。私はこの構成はすべてのパッケージの最新の利用可能なものです。
要求された例で残りのテキストを完全に置き換えました。これは@ARoundアドバイスに限定されているようです。 @beforeは大丈夫です。
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 \ ispej \ ancestJweaver \ 1.8.1 \ ispejweaver-1.8.1.jar
テスト中のクラス(私は先に進むことを明らかに投げることを宣言しているため、この単純なテストは何も投げませんでした。
.
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();
}
.
最後にもう一度1回、これは実際にはAncepTarget(TestFirstMethodメソッドの1行目)をインスタンス化しようとしたときに実際にスローされます。
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)
. 解決
問題は、ネイティブアスペクトJYNTAX(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();
}
}
.
正しいネイティブアスペクトJの構文:
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();
}
}
.