【问题标题】:PowerMock and javassist conflictPowerMock 和 javassist 冲突
【发布时间】:2017-06-28 14:12:24
【问题描述】:

当我尝试在这个版本上运行我的单元测试时,我遇到了一个问题:

PowerMock - 1.6.5

javaassist - 3.12.1.GA

java8

我得到了这个:

java.lang.IllegalStateException: Failed to transform class with name com.energyict.ems.mstr.MstrSessionManager. Reason: java.io.IOException: invalid constant type: 15

    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:283)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:192)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:71)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
    at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:439)
    at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:420)
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
    at java.lang.Class.createAnnotationData(Class.java:3521)
    at java.lang.Class.annotationData(Class.java:3510)
    at java.lang.Class.getAnnotation(Class.java:3415)
    at org.junit.internal.MethodSorter.getDeclaredMethods(MethodSorter.java:52)
    at org.junit.internal.runners.TestClass.getAnnotatedMethods(TestClass.java:45)
    at org.junit.internal.runners.MethodValidator.validateTestMethods(MethodValidator.java:71)
    at org.junit.internal.runners.MethodValidator.validateStaticMethods(MethodValidator.java:44)
    at org.junit.internal.runners.MethodValidator.validateMethodsForDefaultRunner(MethodValidator.java:50)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate(PowerMockJUnit44RunnerDelegateImpl.java:108)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.<init>(PowerMockJUnit44RunnerDelegateImpl.java:70)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl.<init>(PowerMockJUnit47RunnerDelegateImpl.java:42)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl.<init>(PowerMockJUnit49RunnerDelegateImpl.java:25)
    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.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:172)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:48)
    at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:113)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:71)
    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 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.RuntimeException: java.io.IOException: invalid constant type: 15
    at javassist.CtClassType.getClassFile2(CtClassType.java:203)
    at javassist.CtClassType.subtypeOf(CtClassType.java:303)
    at javassist.CtClassType.subtypeOf(CtClassType.java:318)
    at javassist.compiler.MemberResolver.compareSignature(MemberResolver.java:247)
    at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:119)
    at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:96)
    at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:704)
    at javassist.expr.NewExpr$ProceedForNew.setReturnType(NewExpr.java:243)
    at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:146)
    at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
    at javassist.compiler.TypeChecker.atVariableAssign(TypeChecker.java:248)
    at javassist.compiler.TypeChecker.atAssignExpr(TypeChecker.java:217)
    at javassist.compiler.ast.AssignExpr.accept(AssignExpr.java:38)
    at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:241)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:329)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:350)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atIfStmnt(CodeGen.java:404)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:354)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.Javac.compileStmnt(Javac.java:568)
    at javassist.expr.NewExpr.replace(NewExpr.java:206)
    at org.powermock.core.transformers.impl.AbstractMainMockTransformer$PowerMockExpressionEditor.edit(AbstractMainMockTransformer.java:436)
    at javassist.expr.ExprEditor.loopBody(ExprEditor.java:211)
    at javassist.expr.ExprEditor.doit(ExprEditor.java:90)
    at javassist.CtClassType.instrument(CtClassType.java:1374)
    at org.powermock.core.transformers.impl.ClassMockTransformer.transformMockClass(ClassMockTransformer.java:65)
    at org.powermock.core.transformers.impl.AbstractMainMockTransformer.transform(AbstractMainMockTransformer.java:247)
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:264)
    ... 57 more
Caused by: java.io.IOException: invalid constant type: 15
    at javassist.bytecode.ConstPool.readOne(ConstPool.java:1090)
    at javassist.bytecode.ConstPool.read(ConstPool.java:1033)
    at javassist.bytecode.ConstPool.<init>(ConstPool.java:149)
    at javassist.bytecode.ClassFile.read(ClassFile.java:737)
    at javassist.bytecode.ClassFile.<init>(ClassFile.java:108)
    at javassist.CtClassType.getClassFile2(CtClassType.java:190)
    ... 86 more

但是当我尝试更改 javaassist 版本时,例如:3.20.0-GA

        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.20.0-GA</version>
        </dependency>

我收到下一个错误:

java.lang.NoSuchMethodError: javassist.CtMethod.hasAnnotation(Ljava/lang/Class;)Z

    at org.powermock.core.transformers.impl.TestClassTransformer.removeTestAnnotationsForTestMethodsThatRunOnOtherClassLoader(TestClassTransformer.java:189)
    at org.powermock.core.transformers.impl.TestClassTransformer.transform(TestClassTransformer.java:203)
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:264)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:192)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:71)
    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:161)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:48)
    at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:113)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:71)
    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 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)


Process finished with exit code -1

有人可以提出解决方案吗?

【问题讨论】:

  • 仅作记录:您明白只有在您必须测试无法修改的第 3 方代码时才应该使用 PowerMock(ito)?因为当你编写自己的代码时,你认为你需要 PowerMock 来测试它;那么您的问题是您正在编写难以测试的代码。易于测试的代码不需要 PowerMock(ito)。

标签: maven junit4 powermock javassist


【解决方案1】:

PowerMock 1.6.5 已经有 3.20.0-GA 作为依赖项。来自 pom.xml

         <javaassist.version>3.20.0-GA</javaassist.version>
         <dependency>
             <groupId>org.javassist</groupId>
             <artifactId>javassist</artifactId>
             <version>${javaassist.version}</version>
             <scope>compile</scope>
         </dependency>

此外,该方法是在 Javassist 3.11 中添加的。

 /**
 * Returns true if the class has the specified annotation type.
 *
 * @param clz the annotation type.
 * @return <code>true</code> if the annotation is found, otherwise <code>false</code>.
 * @since 3.11
 */
public boolean hasAnnotation(Class clz) {
    return hasAnnotation(clz.getName());
}

请检查您是否没有其他版本的 Javassist

由于 PowerMock 1.6.6 具有 3.21.0-GA 作为依赖项。 changelog

  • 将 Javaassist 依赖项从 3.20.0-GA 升级到版本 3.21.0-GA

【讨论】:

  • 感谢您的回答,但是 1.6.5 PowerMock 版本有什么解决方案吗?
  • 这是我的堕落。我错过了您需要 3.20.0-GA。我不知道为什么,但我认为您需要更多的 3.20.0-GA。我更新了答案。请检查您的类路径。
  • 其实我不需要特定版本的javaassist,我只是想让我的项目能够构建。问题是我使用的是 PowerMock 1.6.5,在将目标 jdk 更新为 &lt;target-jdk&gt;1.8&lt;/target-jdk&gt; 后,我开始面临上述问题。
  • 根据 GitHub github.com/jboss-javassist/javassist/issues/115 上的问题,您的想法是正确的。您需要 3.20.0-GA 或更高版本。
  • 我对第二个异常感到困惑。它指出您有其他版本的 Javassist,早于 3.11,作为传递依赖。我的建议,检查依赖树
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 2012-09-10
  • 2012-08-24
  • 2021-03-06
相关资源
最近更新 更多