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:
Des discussions sur Google à propos de powermock - mockito & Java-8
Exclusion de Java assist de powermock et ajout de Java assist 3.19.0-GA
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>
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.
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"))
}
}
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.
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.
Ce problème est lié à un problème de compatibilité avec Java 8. Pourriez-vous exécuter vos tests sur Java 7?
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.