升级至Oracle JDK 11后TestNG无法实例化测试类问题
问题:JDK11下TestNG+PowerMock测试类无法实例化
原本在Oracle JDK8+Eclipse环境正常运行的TestNG测试用例,升级到Oracle JDK11后抛出org.testng.TestNGException: Cannot instantiate class com.aa.bb.test.SomeTest异常。
现有依赖配置
pom.xml中相关依赖:
<dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.8</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-core</artifactId> <version>1.7.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>1.7.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-testng</artifactId> <version>1.7.3</version> <scope>test</scope> </dependency>
已尝试升级TestNG到7.x.x、PowerMock相关依赖到2.x.x,但问题依旧。
完整堆栈信息
org.testng.TestNGException: Cannot instantiate class com.aa.bb.test.SomeTest at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:38) at org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:387) at org.testng.internal.ClassHelper.createInstance(ClassHelper.java:299) at org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:110) at org.testng.internal.ClassImpl.getInstances(ClassImpl.java:186) at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:120) at org.testng.TestRunner.initMethods(TestRunner.java:409) at org.testng.TestRunner.init(TestRunner.java:235) at org.testng.TestRunner.init(TestRunner.java:205) at org.testng.TestRunner.<init>(TestRunner.java:160) at org.testng.remote.support.RemoteTestNG6_5$1.newTestRunner(RemoteTestNG6_5.java:27) at org.testng.remote.support.RemoteTestNG6_5$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG6_5.java:63) at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:561) at org.testng.SuiteRunner.init(SuiteRunner.java:157) at org.testng.SuiteRunner.<init>(SuiteRunner.java:111) at org.testng.TestNG.createSuiteRunner(TestNG.java:1273) at org.testng.TestNG.createSuiteRunners(TestNG.java:1260) at org.testng.TestNG.runSuitesLocally(TestNG.java:1114) at org.testng.TestNG.run(TestNG.java:1031) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) Caused by: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:29)
解决方案
1. 补充JDK9+必需的PowerMock代理依赖
PowerMock 2.x.x支持JDK11,但必须添加powermock-module-testng-agent依赖,这是JDK模块化环境下的核心配置,之前大概率遗漏了这个依赖。更新后的依赖示例:
<!-- TestNG 7.x 兼容PowerMock 2.x --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.7.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-core</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-testng</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <!-- JDK9+必须添加的TestNG代理依赖 --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-testng-agent</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency>
2. 配置TestNG使用PowerMock的实例化工厂
在测试类中添加@ObjectFactory注解,指定PowerMock的对象工厂替代TestNG默认实现,解决类实例化失败问题:
import org.powermock.modules.testng.PowerMockObjectFactory; import org.testng.annotations.ObjectFactory; public class SomeTest { @ObjectFactory public ObjectFactory getObjectFactory() { return new PowerMockObjectFactory(); } // 测试方法... }
3. Eclipse中添加JDK11模块访问权限参数
如果项目是模块化结构(含module-info.java),需要在TestNG运行配置中添加VM参数,允许PowerMock访问JDK内部模块:
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED
添加路径:Eclipse → Run Configurations → 对应TestNG配置 → Arguments → VM arguments中粘贴上述内容。
4. 清理重建项目
- 执行
mvn clean install清理旧依赖和编译文件 - Eclipse中执行
Project → Clean清除本地编译缓存 - 重新运行测试用例
内容的提问来源于stack exchange,提问作者7msseven
相关产品推荐
相关产品推荐

