运行 Maven 集成测试时获取“在分支目标处期望堆栈图帧”
Posted
技术标签:
【中文标题】运行 Maven 集成测试时获取“在分支目标处期望堆栈图帧”【英文标题】:Getting "Expecting a stackmap frame at branch target" when running Maven integration testing 【发布时间】:2015-10-12 14:07:01 【问题描述】:我在这个版本的 Java 中使用 Maven 3.2.3
davea$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
当我跑步时
mvn clean install
我在集成测试中遇到如下错误……
testFindSampleUsersByCodeAscByDefault(org.mainco.subco.user.service.SampleUserService2IT) Time elapsed: 2.204 sec <<< ERROR!
java.lang.VerifyError: Expecting a stackmap frame at branch target 57
Exception Details:
Location:
org/mainco/subco/user/service/SampleUserServiceImpl$ValueComparator.compare(Lorg/mainco/subco/user/domain/User;Lorg/mainco/subco/user/domain/User;)I @10: ifnull
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: 2ab4 001b 2bb9 002e 0200 c600 2f2a b400
0x0000010: 1b2b b900 2e02 00c0 0030 b600 34c6 001c
0x0000020: 2ab4 001b 2bb9 002e 0200 c000 30b6 0034
0x0000030: b600 39b6 003e a700 0512 404e 2ab4 001b
0x0000040: 2cb9 002e 0200 c600 2f2a b400 1b2c b900
0x0000050: 2e02 00c0 0030 b600 34c6 001c 2ab4 001b
0x0000060: 2cb9 002e 0200 c000 30b6 0034 b600 39b6
0x0000070: 003e a700 0512 403a 042d 1904 b600 4436
0x0000080: 0515 0599 0016 2d19 04b6 0044 2d19 04b6
0x0000090: 0044 b800 4a6c a700 0403 3606 1506 2ab4
0x00000a0: 0023 9900 0702 a700 0404 a000 0502 ac04
0x00000b0: ac
at org.mainco.subco.user.service.SampleUserServiceImpl.findSampleUsers(SampleUserServiceImpl.java:439)
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:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy98.findSampleUsers(Unknown Source)
at org.mainco.subco.user.service.SampleUserService2IT.testFindSampleUsersByCodeAscByDefault(SampleUserService2IT.java:215)
这是我的编译器插件的配置方式……
<profile>
<id>jdk-8</id>
<activation>
<jdk>1.8</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-proc:none</compilerArgument>
<fork>true</fork>
</configuration>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
这是我的故障保险的配置方式
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<reuseForks>true</reuseForks>
<argLine>-Xmx4096m -XX:MaxPermSize=512M -XX:-UseSplitVerifier $itCoverageAgent</argLine>
<skipTests>$skipAllTests</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
任何想法如何防止我看到这些奇怪的“期望在分支目标处出现堆栈图帧”错误?
编辑:
我正在使用这些依赖项(正如 cmets 推测的那样,这些是问题):
[INFO] +- org.springframework:spring-aop:jar:3.2.11.RELEASE:compile
...
[INFO] +- org.aspectj:aspectjweaver:jar:1.8.6:compile
[INFO] +- org.aspectj:aspectjrt:jar:1.8.6:compile
【问题讨论】:
Maven 与你无关的问题。您的环境中有一个字节码处理工具与最近的字节码功能不兼容,而“最近”表示“几年前”,但在 Java 8 之前,您使用的-XX:-UseSplitVerifier
选项有助于忽略这些问题。首先怀疑是 AOP 框架和覆盖代理。第一次尝试应该是更新所有内容。
我删除了 $itCoverageAGent 选项(没有改变任何东西)并使用 Spring AOP 3.2.11.RELEASE 和 aspectj-weaver 1.8.6(最新)。更新 Spring AOP 不是一个选项。你是说这个版本的 Spring AOP 与 Java 8 不兼容吗?
我不详细了解这些库。我只是说,其中一个肯定是原因。快速搜索发现***.com/a/27556298/2711488;也许这有帮助。
我很难相信这是原因。当我运行一个单独的测试文件时,比如“mvn clean test -Dtest=UserServiceIT”,一切都会顺利通过。只有在所有测试一起运行时运行“mvn clean install”时,我才会看到这些 VerifyErrors 弹出。
好吧,为了重现它,代码必须包含 AOP 尝试检测的方法,以及该进程可以丢弃的 StackMapFrame
s。这需要足够复杂的代码,例如没有分支的代码没有StackMapTable
属性,因此没有要丢弃的帧。但是如果你怀疑你的环境中有另一个字节码操作库,你可以检查一下。我并没有声称确切地知道,谁该负责,我只是说,那个错误是关于什么的……
【参考方案1】:
在java8之前,你可以在启动jvm时添加-XX:-UseSplitVerifier
的arg项来解决这个问题;
UseSplitVerifier
arg 项已被 java8 删除,但您也可以使用-noverify
进行替换
【讨论】:
【参考方案2】:我在迁移到 JDK 8 时遇到了同样的问题。代码构建良好,只是在运行单元测试时出现了这些错误。我看到您正在使用-XX:-UseSplitVerifier
,这对我也不起作用。我在某处发现了一个简短的宣传,我应该使用-noverify
,而不是在JDK 8 中使用-XX:-UseSplitVerifier
。我试了一下,它对我有用。
希望这会有所帮助。
【讨论】:
你在哪里设置-noverify?我将它设置为 MAVEN_OPTS 但它不适合我以上是关于运行 Maven 集成测试时获取“在分支目标处期望堆栈图帧”的主要内容,如果未能解决你的问题,请参考以下文章