Closed VicDelacroix closed 2 years ago
估计是原始代码恰好有某些特殊的字节码序列,导致Testable修改后的字节码引用了名称为空的类。
这种情况没有现场凭空不太好猜测,初步看起来比较像是Mock类里的代码导致的,能将insert
这个Mock方法里的代码脱敏贴出来吗?
@linfan 忘了有开源版的了,定位问题应该够了 https://github.com/ctripcorp/dal com.ctrip.platform.dal.dao.DalTableDao#insert(DalHints hints, KeyHolder keyHolder, T daoPojo)
可以的,我这周内抽空复现一下~
@VicDelacroix 我尝试写了一个包含DalTableDao#insert
调用的方法,并在单元测试中对DalTableDao#insert
方法进行Mock,但并未复现问题。
能否帮忙提供一个可复现上述问题的代码示例呢(简单的测试用例和Mock定义即可)?
@linfan 有可能和CGLIB有关吗,调用被mock方法的方法由CGLIB处理过,功能类似Spring的@Transactional
public class TestedService implements ApplicationContextAware { private TDao dao;
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
dao= applicationContext.getBean(TDao .class);
}
@DalTransactional
public Object tested(Object args) {
dao.insert(new T());
}
}
public class TDao {
private DalTableDao
public int insert(DalHints hints, KeyHolder keyHolder, TdaoPojo) throws SQLException {
if (null == daoPojo) {
return 0;
}
hints = DalHints.createIfAbsent(hints);
return client.insert(hints, keyHolder, daoPojo);
}
}
有这个可能,CGLIB也会对字节码进行修改,两边在某种情况下会发生巧合冲突。
对于Testable来说,使用MockScope.ASSOCIATED
只是会在调用Mock方法体之前增加一次来源检查,没有动态生成类名,应该不会直接造成“Illegal class name "" ”错误。在没有现场或可重现代码的情况下,目前的线索依然不太有用。
JDK11,win64,Idea,JUnit4 testable version 0.6.7
方法签名 public int insert(ClassA a, ClassB b, ClassC c)
错误堆栈没看到太多的有用信息,去掉ASSOCIATED后正常 java.lang.ClassFormatError: Illegal class name "" in class file xxxTest$Mock