Powermock - java.lang.IllegalStateException:无法转换类

时间:2015-09-29 22:17:49

标签: java junit mockito powermock

说明

我正在尝试从类中测试静态方法。我使用powerMock(1.6.2)+ mockito(1.10.19)与Junit4(4.12)& java8。

问题:

获取错误:“无法转换名为com.gs.ops.domain.StaticClass的类原因:java.io.IOException:无效的常量类型:18”

解决方案:

  1. 使用powermock发布用Google搜索的主题 - mockito& java的8

  2. 从powermock中删除java协助并添加了java协助3.19.0-GA

  3. 尝试了不同版本的powermock(1.5.4,1.6.2 ......)

  4. 以下是异常堆栈跟踪:

     java.lang.IllegalStateException: Failed to transform class with name com.StaticClass. Reason: java.io.IOException: invalid constant type: 18
            at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:266)
            at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
            at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:68)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            at java.lang.Class.forName0(Native Method)
            at java.lang.Class.forName(Class.java:340)
            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:408)
            at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
            at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
            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:33)
            at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
        Caused by: java.lang.RuntimeException: java.io.IOException: invalid constant type: 18
            at javassist.CtClassType.getClassFile2(CtClassType.java:203)
            at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:110)
            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.MainMockTransformer$PowerMockExpressionEditor.edit(MainMockTransformer.java:418)
            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.MainMockTransformer.transform(MainMockTransformer.java:74)
            at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:251)
            ... 24 more
        Caused by: java.io.IOException: invalid constant type: 18
            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)
            ... 49 more
    

    Pom文件:

    <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-api-mockito</artifactId>
                <version>1.6.2</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-module-junit4</artifactId>
                <version>1.6.2</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit</groupId>
                        <artifactId>junit</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.powermock</groupId>
                        <artifactId>powermock-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.powermock</groupId>
                        <artifactId>powermock-reflect</artifactId>
                    </exclusion>
                </exclusions>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.19.0-GA</version>
            </dependency>
    

8 个答案:

答案 0 :(得分:30)

Powermock 1.6.3使用javassist 3.15.2-GA,它不支持某些类型。使用3.18.2-GA javassist为我工作。您可能希望覆盖项目中的依赖项。

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

您可能面临解决方案所在的另一个问题Mockito + PowerMock LinkageError while mocking system class

希望这有帮助。

答案 1 :(得分:8)

因此javassist之前的3.18.2(字节码工具包)似乎存在问题,因为已经解决了JIRA ticket-223

1 - 要在pom.xml中查找javassist版本,可以使用mvn dependency任务

$ mvn dependency:tree | grep javassist
[INFO] |     \- org.javassist:javassist:jar:3.14.0-GA:compile

powermock-module-junit4-rule

使用
[INFO] +- org.powermock:powermock-module-junit4-rule:jar:1.4.9:test
[INFO] |  +- org.powermock:powermock-classloading-base:jar:1.4.9:test
[INFO] |  \- org.powermock:powermock-core:jar:1.4.9:compile
[INFO] |     \- org.javassist:javassist:jar:3.14.0-GA:compile

2 - 因此,明确更新javassist版本>= 3.18.2应该有效。

就我而言,我正在使用3.20.0-GA

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

工作例如。使用scalatest

@PowerMockIgnore(Array("javax.management.*"))
@RunWith(classOf[PowerMockRunner])
@PrepareForTest(Array(classOf[Configurator]))
class LogServiceSpec {

  @Test
  def initialises_log4j2_on_each_instance_call() {
    PowerMockito.mockStatic(classOf[Configurator])

    val logService1 = new LogService
    PowerMockito.verifyStatic(Mockito.times(1))
    Configurator.initialize(Matchers.anyString(), Matchers.eq("log4j.config"))
  }
}

答案 2 :(得分:5)

这是由于依赖性冲突引起的。解决依赖冲突是解决此问题的一种方法,另一种方法是重新排序pom.xml中的<dependency></dependency>元素。将powermock依赖性声明移动到<dependencies></dependencies>部分的顶部。这是一个完整的黑客,解决它的正确方法是解决依赖冲突。

要识别这些冲突,您可以使用命令“mvn dependency:tree”。这是我的应用程序的依赖树,我遇到了同样的问题。请注意,树中有两个“javassist”依赖项。

[INFO] +- org.mockito:mockito-core:jar:1.10.19:test
[INFO] |  +- org.hamcrest:hamcrest-core:jar:1.1:compile
[INFO] |  \- org.objenesis:objenesis:jar:2.1:compile
[INFO] +- org.powermock:powermock-module-junit4:jar:1.6.4:test
[INFO] |  \- org.powermock:powermock-module-junit4-common:jar:1.6.4:test
[INFO] |     +- org.powermock:powermock-core:jar:1.6.4:compile
[INFO] |     <span style="background-color: #FFFF00">|  \- org.javassist:javassist:jar:3.20.0-GA:compile</span>
[INFO] |     \- org.powermock:powermock-reflect:jar:1.6.4:compile
[INFO] +- org.powermock:powermock-api-mockito:jar:1.6.4:compile
[INFO] |  \- org.powermock:powermock-api-support:jar:1.6.4:compile
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.14:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.7.14:compile
[INFO] |  \- log4j:log4j:jar:1.2.17:compile
[INFO] |  +- org.apache.struts:struts2-core:jar:2.3.16.3-atlassian-6:provided
[INFO] |  |  \- ognl:ognl:jar:3.0.6:provided
<span style="background-color: #FFFF00">
[INFO] |  |     \- javassist:javassist:jar:3.11.0.GA:provided</span>
[INFO] |  +- com.atlassian:webwork-compat:jar:1.24:provided
[INFO] |  +- org.freemarker:freemarker:jar:2.3.16-atlassian-34:provided
[INFO] |  |  \- logkit:logkit:jar:1.2:provided
[INFO] |  +- opensymphony:sitemesh:jar:2.5-atlassian-6:provided
[INFO] |  +- commons-fileupload:commons-fileupload:jar:1.3.1:provided
[INFO] |  +- org.tuckey:urlrewritefilter:jar:4.0.3:provided
[INFO] |  +- velocity-tools:velocity-tools:jar:1.2:provided
[INFO] |  +- commons-dbutils:commons-dbutils:jar:1.3:provided
[INFO] |  +- org.hamcrest:hamcrest-all:jar:1.3:provided
[INFO] |  +- com.atlassian.bamboo:atlassian-user-crowd-provider:jar:5.10.0:provided
[INFO] |  |  +- com.atlassian.crowd:crowd-integration-client-rest:jar:2.7.2:provided
[INFO] |  |  |  \- com.atlassian.crowd:crowd-integration-client-common:jar:2.7.2:provided
[INFO] |  |  |     \- com.atlassian.security:atlassian-cookie-tools:jar:3.2:provided
[INFO] |  |  +- com.atlassian.crowd:crowd-integration-api:jar:2.7.2:provided
[INFO] |  |  |  \- com.atlassian.crowd:embedded-crowd-api:jar:2.7.2:provided
[INFO] |  |  +- com.atlassian.user:atlassian-user-api:jar:4.1.1:provided
[INFO] |  |  |  \- com.opensymphony.propertyset:api:jar:1.6.0-m1:provided
[INFO] |  |  +- com.atlassian.user:atlassian-user-ldap:jar:4.1.1:provided
[INFO] |  |  +- org.acegisecurity:acegi-security:jar:1.0.4:provided
[INFO] |  |  |  \- oro:oro:jar:2.0.8:provided
[INFO] |  |  \- com.atlassian.crowd:crowd-integration-seraph25:jar:2.7.2:provided
[INFO] |  +- javax.xml.stream:stax-api:jar:1.0-2:provided
[INFO] |  +- com.atlassian.core:atlassian-core:jar:5.0.2:provided
[INFO] |  |  \- com.atlassian.image:atlassian-image-consumer:jar:1.0.1:provided
[INFO] |  +- org.apache.maven:maven-embedder:jar:3.0.4:provided
[INFO] |  |  +- org.apache.maven:maven-settings:jar:3.0.4:provided
[INFO] |  |  +- org.apache.maven:maven-plugin-api:jar:3.0.4:provided
[INFO] |  |  +- org.apache.maven:maven-model-builder:jar:3.0.4:provided
[INFO] |  |  +- org.apache.maven:maven-compat:jar:3.0.4:provided
[INFO] |  |  +- org.codehaus.plexus:plexus-classworlds:jar:2.4:provided
[INFO] |  |  +- org.sonatype.sisu:sisu-inject-plexus:jar:2.3.0:provided
[INFO] |  |  |  \- org.sonatype.sisu:sisu-inject-bean:jar:2.3.0:provided
[INFO] |  |  +- org.codehaus.plexus:plexus-component-annotations:jar:1.5.5:provided
[INFO] |  |  +- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:provided
[INFO] |  |  +- org.sonatype.plexus:plexus-cipher:jar:1.7:provided
[INFO] |  |  \- commons-cli:commons-cli:jar:1.2:provided
[INFO] |  +- org.apache.maven:maven-model:jar:3.0.4:provided
[INFO] |  +- com.octo.captcha:jcaptcha:jar:2.0-alpha-1:provided
[INFO] |  +- com.octo.captcha:jcaptcha-api:jar:2.0-alpha-1:provided
[INFO] |  +- com.jhlabs:filters:jar:2.0.235:provided
[INFO] |  +- org.apache.struts:struts2-sitemesh-plugin:jar:2.1.8.1:provided
[INFO] |  +- org.slf4j:jul-to-slf4j:jar:1.7.10:provided
[INFO] |  +- com.atlassian.plugins:atlassian-plugins-schema:jar:4.0.5:provided
[INFO] |  |  \- com.atlassian.plugins:atlassian-plugins-osgi:jar:4.0.5:provided
[INFO] |  |     +- com.atlassian.plugins:atlassian-plugins-osgi-events:jar:4.0.5:provided
[INFO] |  |     +- biz.aQute.bnd:biz.aQute.bndlib:jar:2.4.1:provided
[INFO] |  |     +- org.apache.felix:org.apache.felix.framework:jar:4.2.1:provided
[INFO] |  |     \- org.twdata.pkgscanner:package-scanner:jar:0.9.5:provided
[INFO] |  \- xerces:xercesImpl:jar:2.11.0:provided
[INFO] |     \- xml-apis:xml-apis:jar:1.4.01:provided
[INFO] +- junit:junit:jar:4.12:test
[INFO] +- info.cukes:cucumber-java:jar:1.2.4:test
[INFO] |  \- info.cukes:cucumber-core:jar:1.2.4:test
[INFO] |     +- info.cukes:cucumber-html:jar:0.2.3:test
[INFO] |     +- info.cukes:cucumber-jvm-deps:jar:1.0.5:test
[INFO] |     \- info.cukes:gherkin:jar:2.12.2:test
[INFO] +- info.cukes:cucumber-junit:jar:1.2.4:test
[INFO] +- com.atlassian.plugins:atlassian-plugins-osgi-testrunner:jar:1.2.3:test
[INFO] |  +- org.apache.wink:wink-client:jar:1.1.3-incubating:test
[INFO] |  |  +- org.apache.wink:wink-common:jar:1.1.3-incubating:test
[INFO] |  |  |  \- org.apache.geronimo.specs:geronimo-annotation_1.1_spec:jar:1.0:test
[INFO] |  |  +- javax.xml.bind:jaxb-api:jar:2.2:test
[INFO] |  |  \- com.sun.xml.bind:jaxb-impl:jar:2.2.1.1:test
[INFO] |  +- commons-io:commons-io:jar:1.4:provided
[INFO] |  \- com.atlassian.upm:upm-api:jar:2.15:test
[INFO] +- javax.ws.rs:jsr311-api:jar:1.1.1:provided
[INFO] +- com.google.code.gson:gson:jar:2.2.2-atlassian-1:compile
[INFO] +- com.mashape.unirest:unirest-java:jar:1.3.3:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.3.1:compile
[INFO] |  +- org.apache.httpcomponents:httpcore:jar:4.3:compile
[INFO] |  \- commons-codec:commons-codec:jar:1.6:compile
[INFO] +- org.apache.httpcomponents:httpasyncclient:jar:4.0:compile
[INFO] |  \- org.apache.httpcomponents:httpcore-nio:jar:4.3:compile
[INFO] +- org.apache.httpcomponents:httpmime:jar:4.3.1:compile
[INFO] +- org.json:json:jar:20090211:compile
[INFO] +- com.fasterxml.jackson.core:jackson-core:jar:2.3.3:compile
[INFO] \- com.fasterxml.jackson.core:jackson-databind:jar:2.3.3:compile
[INFO]    \- com.fasterxml.jackson.core:jackson-annotations:jar:2.3.0:compile

我希望这会有所帮助。

答案 3 :(得分:1)

在我的例子中,&#34; java.io.IOException:无效的常量类型:18&#34;是由我的类路径中的多个版本的javassist库引起的 - 包括3.12.1.GA和3.18.2-GA。当我删除旧版本时,问题就消失了。

答案 4 :(得分:0)

不是真正的答案!使用JDK8运行Maven构建并生成Java6字节代码时出现类似错误。我的pom看起来像这样:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <compilerVersion>1.6</compilerVersion>
                <source>1.6</source>
                <target>1.6</target>
                <maxmem>2000m</maxmem>
                <fork>true</fork>
            </configuration>
        </plugin>

当我恢复到JDK6时,我不再收到错误。

答案 5 :(得分:0)

在我的情况下,JRE系统库->在JavaSE-1.7上设置了执行环境,但是唯一安装的JRE是JRE1.8。因此它指向的是Java 8而不是Java7。一旦我移到Java 7,它对我来说就可以正常工作。

enter image description here

答案 6 :(得分:0)

此问题与Java 8的兼容性问题有关。您可以在Java 7上执行测试吗?

答案 7 :(得分:0)

在终端上运行“ MVN依赖项:树| grep javassist”。如果在非测试库和测试库中显示javaassist依赖项。现在,您只需要在运行时将其排除即可进行测试。因此,执行此操作的方法是在以下行上添加一个构建插件:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <classpathDependencyExcludes>
                    <classpathDependencyExcludes>javassist:javassist</classpathDependencyExcludes>
                </classpathDependencyExcludes>
            </configuration>
        </plugin>
    </plugins>

请注意,根据您的javassist版本,classpathDependencyExcludes可能会为您更改。

相关问题