You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Log4j1.x升级2.x运行PowerMock测试报invalid constant type:18错误

Log4j版本迁移后PowerMock类转换失败问题

问题现象

将老旧遗留应用从Log4j 1.x版本迁移至2.x版本时,运行测试用例抛出如下异常,参考相关排查帖操作后问题未解决:

java.lang.IllegalStateException: Failed to transform class with name com.ABCTest. Reason: java.io.IOException: invalid constant type: 18
    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 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:31)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:90)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:76)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:49)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:526)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.RuntimeException: java.io.IOException: invalid constant type: 18
    at javassist.CtClassType.getClassFile2(CtClassType.java:207)
    at javassist.CtClassType.getModifiers(CtClassType.java:370)
    at javassist.CtClassType.isInterface(CtClassType.java:358)
    at org.powermock.core.transformers.impl.ClassMockTransformer.transformMockClass(ClassMockTransformer.java:39)
    at org.powermock.core.transformers.impl.AbstractMainMockTransformer.transform(AbstractMainMockTransformer.java:247)
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:264)
    ... 28 more

环境依赖

项目核心Maven依赖树如下:

[INFO] +- org.assertj:assertj-core:jar:3.5.1:test
[INFO] +- junit:junit:jar:4.8.2:test
[INFO] +- org.mockito:mockito-core:jar:1.10.19:test
[INFO] |  +- org.hamcrest:hamcrest-core:jar:1.1:test
[INFO] |  \- org.objenesis:objenesis:jar:2.1:test
[INFO] +- org.powermock:powermock-module-junit4:jar:1.6.5:test
[INFO] |  \- org.powermock:powermock-module-junit4-common:jar:1.6.5:test
[INFO] |     +- org.powermock:powermock-core:jar:1.6.5:test
[INFO] |     |  \- org.javassist:javassist:jar:3.20.0-GA:test
[INFO] |     \- org.powermock:powermock-reflect:jar:1.6.5:test
[INFO] +- org.powermock:powermock-api-mockito:jar:1.6.5:test
[INFO] |  \- org.powermock:powermock-api-mockito-common:jar:1.6.5:test
[INFO] |     \- org.powermock:powermock-api-support:jar:1.6.5:test
[INFO] +- commons-lang:commons-lang:jar:2.4:compile
[INFO] +- commons-codec:commons-codec:jar:1.6:compile
[INFO] +- org.mybatis:mybatis-spring:jar:2.0.1:compile
[INFO] +- org.mybatis:mybatis:jar:3.5.1:compile
[INFO] +- com.sybase:jconnect:jar:7.0.7:compile
[INFO] +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] +- jdbc:jcon3:jar:0:compile
[INFO] +- commons-dbcp:commons-dbcp:jar:1.4:compile
[INFO] |  \- commons-pool:commons-pool:jar:1.5.4:compile
[INFO] +- javax.jms:jms:jar:1.1:compile
[INFO] +- javax.mail:mail:jar:1.4.5:compile
[INFO] |  \- javax.activation:activation:jar:1.1:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.5.6:compile
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.5.6:compile
[INFO] +- org.springframework:spring-test:jar:3.2.9.RELEASE:test
[INFO] +- com.ubs.gfs.sbl.halo:HaloAxisWSClient:jar:29.3.1:compile
[INFO] +- antlr:antlr:jar:2.7.7:compile
[INFO] +- com.ibm.mq:com.ibm.mq.allclient:jar:9.1.2.0:compile
[INFO] |  +- org.bouncycastle:bcprov-jdk15on:jar:1.60:compile
[INFO] |  +- org.bouncycastle:bcpkix-jdk15on:jar:1.60:compile
[INFO] |  \- javax.jms:javax.jms-api:jar:2.0.1:compile
[INFO] +- com.ibm.mq:connector:jar:7.0.1.8:compile
[INFO] +- axis:axis:jar:1.4:compile
[INFO] |  +- org.apache.axis:axis-jaxrpc:jar:1.4:compile
[INFO] |  +- org.apache.axis:axis-saaj:jar:1.4:compile
[INFO] |  \- commons-discovery:commons-discovery:jar:0.2:runtime
[INFO] +- wsdl4j:wsdl4j:jar:1.6.2:compile
[INFO] +- com.oracle:ojdbc6:jar:12.1.0.2:compile
[INFO] \- org.apache.poi:poi:jar:3.0.2-FINAL:compile

已尝试操作

  • 参考公开问题排查帖排查,未解决
  • 手动指定javassist依赖版本为3.18.2-GA,问题仍存在,对应依赖配置如下:
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.18.2-GA</version>
</dependency>

根因分析

报错invalid constant type: 18的核心原因是当前使用的PowerMock 1.6.5版本配套的Javassist字节码处理工具存在兼容性缺陷,无法识别Java 8引入的常量池类型CONSTANT_InvokeDynamic(常量tag值为18)。手动将Javassist降级到3.18.2-GA的操作反而进一步降低了字节码兼容性,无法解决问题。同时当前项目还存在Log4j迁移后的日志依赖冲突问题,会加剧类加载阶段的异常。

解决步骤

按以下顺序操作即可修复问题:

  1. 升级PowerMock相关依赖到1.7.4版本(1.x系列稳定版,原生修复了Java 8字节码解析bug),配套将JUnit升级到4.12及以上版本,保持Mockito 1.10.19版本即可,对应依赖配置:
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
  1. 移除手动添加的低版本javassist依赖,若存在其他依赖引入的javassist版本冲突,显式指定javassist版本为3.24.0-GA,该版本完整支持Java 8所有字节码特性:
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.24.0-GA</version>
    <scope>test</scope>
</dependency>
  1. 修正Log4j2迁移的依赖配置,删除原有org.slf4j:slf4j-log4j12依赖,替换为Log4j2对应的SLF4J绑定包,避免日志桥接冲突:
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version> <!-- 与项目引入的Log4j2核心包版本保持一致即可 -->
</dependency>
  1. 执行mvn clean test命令,全量清理历史编译的class缓存后重新运行测试,即可解决该报错。

内容的提问来源于stack exchange,提问作者PAA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 15:31:57