带有 Javassist 3.18.2-GA 的 Powermock 1.6.3 产生 NoSuchMethodError

Powermock 1.6.3 with Javassist 3.18.2-GA produces a NoSuchMethodError

我将 Powermock 1.6.3 与 Javassist 3.18.2-GA、Mockito 1.10.19、JUnit 4.11 和 JDK1.8 一起使用。我没有编写测试或测试 类,因此,我对这些库不是很熟悉。在 JDK1.7 上构建没有任何问题。我被分配了将应用程序升级到 JDK1.8 的任务,那是我第一次遇到这个错误。此外,错误仅发生在那些模拟 类 且具有静态方法或具有调用静态方法的方法的测试 类 中(测试 类 使用 PowerMockito.mockStatic()方法)。我花了很多时间研究这个问题,我觉得我已经走到了死胡同。任何帮助都感激不尽。这是错误的堆栈跟踪:

java.lang.NoSuchMethodError: javassist.CtMethod.hasAnnotation(Ljava/lang/Class;)Z
at org.powermock.core.transformers.impl.TestClassTransformer.removeTestAnnotationsForTestMethodsThatRunOnOtherClassLoader(TestClassTransformer.java:185)
at org.powermock.core.transformers.impl.TestClassTransformer.transform(TestClassTransformer.java:198)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:250)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:179)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:145)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:61)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:51)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
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:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)

P.S。我已经尝试了 Javassist 和 Powermock 的许多不同组合,但它们都导致了错误。

Power Mock 1.6.3 是 compiled against Javassist 3.20.0-GA。如果这导致 NoSuchMethodError,请确保 class 路径上的其他库不需要更新版本的 Javassist。

遇到了同样的问题。正如 Rafael 所提到的,问题是由于 Javassist 版本存在冲突。由于我的项目是maven构建项目,所以我使用下面的方式查看dependency tree

mvn org.apache.maven.plugins:maven-dependency-plugin:2.10:tree -Dverbose=true

从输出中,我可以找到哪个组件将 Javassist 作为传递依赖项。然后使用 maven dependency exclusion,从类路径中删除了冲突的版本。

希望这会有所帮助