最近将工程从Java11升级到Java17
运行Junit后发现,使用EasyMock的Junit无法正常执行
出现以下错误
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not “opens java.lang” to unnamed module @1d16f93d
java.lang.ExceptionInInitializerError
at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:166)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:144)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:116)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)
at org.easymock.internal.ClassProxyFactory.createEnhancer(ClassProxyFactory.java:257)
at org.easymock.internal.ClassProxyFactory.createProxy(ClassProxyFactory.java:165)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:114)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:88)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:79)
at org.easymock.EasyMock.createMock(EasyMock.java:136)
.....
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1d16f93d
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at net.sf.cglib.core.ReflectUtils$2.run(ReflectUtils.java:56)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:46)
... 44 more
猜想是因为旧版本的EasyMock无法再Java17上运行,于是更新了最新版本的EasyMock(5.2.0),
仍然存在这个问题
根据报错,这个错误似乎是 EasyMock 使用了 cglib库来创建代理对象,于是考虑升级cglib-nodep,但是发现,这个库已经停止更新了,并且不支持Java17,于是查看了EasyMock的Github,在ISSUE看到了,最新的EasyMock使用了byte-buddy来代替cglib,于是删除了cglib,添加byte-buddy和byte-buddy-agent,再次运行,运行成功。
参考链接
https://github.com/easymock/easymock/issues/274
对应的Maven依赖和手动下载的网址
EasyMock
https://mvnrepository.com/artifact/org.easymock/easymock/5.2.0
<!-- https://mvnrepository.com/artifact/org.easymock/easymock -->
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
byte-buddy
https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy/1.14.11
https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy-agent/1.14.11
<!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy-agent -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.14.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.11</version>
</dependency>
如果出现以下的错误
java.lang.RuntimeException: Class mocking requires to have cglib and objenesis librairies in the classpath
是因为缺少objenesis
https://mvnrepository.com/artifact/org.objenesis/objenesis/3.3
<!-- https://mvnrepository.com/artifact/org.objenesis/objenesis -->
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>3.3</version>
</dependency>