一、前言
最近在开发一个功能模块时,在功能自测阶段,通过使用单测测试功能的完整性,在测试单测联通性使用到静态方法测试时,发现单测报错,通过查阅解决方案发现需要对Javaassist包进行排包或者升版本处理。通过排包解决掉单测报错,在部署项目时发现频繁报bean注入失败问题,最终定位发现是因为对Javaassist包排包引起的bean加载失败。故而对Javaassist包相关知识进行学习整理文章如下。
单测相关报错信息如下:
Powermock - java.lang.IllegalStateException: Failed to transform class
解决单测报错的文章链接:
https://stackoverflow.com/questions/32854688/powermock-java-lang-illegalstateexception-failed-to-transform-class
二、问题复现
1、前期准备
首先使用了Spring框架新建一个demo,并写一个简单测试类对问题进行复现。
UserService
的定义:
public interface UserService {void save(User user);
}
UserServiceImpl
的实现代码:
@Service
public class UserServiceImpl implements UserService {private UserDao userDao;@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void save(User user) {userDao.save(user);}
}
这里我们使用了Spring框架的@Service
和@Autowired
注解,以便让Spring框架自动装配UserDao
实例。
但是,在我们的POM文件中,虽然我们添加了对Spring框架的依赖,但是并没有添加Javaassist库的依赖。而UserServiceImpl
中确实使用了Javaassist库来进行字节码操作, UserServiceImpl
的具体实现代码:
public class UserServiceImpl implements UserService {// ...private static final String USER_CLASS_NAME = "com.example.User";private static final Class<?> USER_CLASS;static {try {USER_CLASS = Class.forName(USER_CLASS_NAME);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}public void save(User user) {try {// 创建一个ClassPool对象ClassPool cp = ClassPool.getDefault();// 从ClassPool中获取一个CtClass对象CtClass ctClass = cp.get(USER_CLASS_NAME);