一、前言
最近在開發一個功能模組時,在功能自測階段,透過使用單測測試功能的完整性,在測試單測聯通性使用到靜態方法測試時,發現單測報錯,透過查閱解決方案發現需要對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;
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public 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);