web-dev-qa-db-fra.com

Powermock - Java.lang.IllegalStateException: Echec de la transformation de la classe

La description:

J'essaie de tester une méthode statique à partir d'une classe. J'utilise powerMock (1.6.2) + mockito (1.10.19) pour se moquer de Junit4 (4.12) & Java8.

Problème:

Obtention de l'erreur: "Échec de la transformation de la classe avec le nom com.gs.ops.domain.StaticClass Reason: Java.io.IOException: type de constante non valide: 18"

Solutions essayées:

  1. Des discussions sur Google à propos de powermock - mockito & Java-8

  2. Exclusion de Java assist de powermock et ajout de Java assist 3.19.0-GA

  3. Essayé différentes versions de powermock (1.5.4, 1.6.2 ...)

Ci-dessous la trace de la pile des exceptions:

 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

Fichier 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>
21
Lucky1989

Powermock 1.6.3 utilise javassist 3.15.2-GA, qui ne prend pas en charge certains types. Utiliser javassist 3.18.2-GA a fonctionné pour moi. Vous souhaiterez peut-être remplacer la dépendance dans votre projet. 

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

Vous pouvez faire face à un autre problème pour lequel la solution se trouve ici Mockito + PowerMock LinkageError en moquant la classe système

J'espère que cela t'aides.

27
JDev

Il semble donc y avoir un problème avec javassist (boîte à outils bytecode) avant 3.18.2, car il existe un JIRA ticket-223 résolu. 

1 - Pour trouver la version de javassist dans votre pom.xml, vous pouvez utiliser la tâche mvn dependency

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

qui est utilisé par le 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 - Ainsi, la mise à jour de la version javassist de manière explicite vers n'importe quelle version >= 3.18.2 devrait fonctionner.

Comme, dans mon cas, j'utilise l'utilisation de 3.20.0-GA

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

Travaillant par exemple avec 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"))
  }
}
7
prayagupd

Cela est dû au conflit de dépendances. La résolution des conflits de dépendances est un moyen de résoudre ce problème et une autre consiste à réorganiser les éléments <dependency></dependency> dans votre pom.xml. Déplacez les déclarations de dépendance powermock en haut de la section <dependencies></dependencies>. C'est un hack complet et la bonne façon de le résoudre serait de résoudre les conflits de dépendance.

Pour identifier ces conflits, vous pouvez utiliser la commande "mvn dependency: tree". Voici l'arbre de dépendance de mon application pour laquelle j'ai rencontré le même problème. Notez qu'il existe deux dépendances de "javassist" dans l'arbre.

[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

J'espère que ça aide.

5
Swarup Donepudi

Dans mon cas, une exception "Java.io.IOException: type de constante non valide: 18" a été provoquée par plusieurs versions des bibliothèques javassist dans mon chemin de classe, à la fois 3.12.1.GA et 3.18.2-GA. Le problème a disparu quand j'ai enlevé l'ancien.

1
k6ps

Ce problème est lié à un problème de compatibilité avec Java 8. Pourriez-vous exécuter vos tests sur Java 7? 

0
Aguid

Dans mon cas, JRE System Library -> Execution Environment a été configuré sur JavaSE-1.7, mais le seul JRE installé était JRE1.8. Cela désignait donc Java 8 à la place de Java 7. Une fois que je suis passé à Java 7, cela a bien fonctionné pour moi.

 enter image description here

0
Amit Garg

Pas vraiment une réponse! J'ai eu une erreur similaire lors de l'exécution d'une construction Maven avec JDK8 et lors de la génération de code octet Java6. Mon pom ressemble à ceci:

        <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>

Quand je suis revenu à JDK6, je n'ai plus l'erreur.

0
CodeClimber