为什么PowerMock使用javassist libraray和Mockito不使用

问题描述 投票:0回答:1

我不明白为什么PowerMock使用javassist库而Mockito不是。

mockito powermock
1个回答
2
投票

关于Java中代码生成库的大多数对话都围绕着三个库:cglib,javassist和ByteBuddy。 Mockito以前是在cglib上,但现在使用ByteBuddy作为默认代码生成器。

作为ByteBuddy作者Rafael Winterhalter notes here

javassist提供了一个用于修改类的API,而不仅仅是对它们进行子类化。这些API还允许字节代码级操作,而cglib仅允许多个硬编码拦截。

虽然我不是任何这些模拟框架或库的贡献者,但值得注意的是,Powermock部分地通过编辑类实现来拦截对编译的字节码中的私有,静态和最终方法和类的调用。这可能解释了使用Powermock的javassist的要求:cglib无法编辑现有的类。相比之下,Mockito需要更简单的代码生成才能生成给定类的子类;这是cglib和ByteBuddy编写提供的功能。

请注意,open Powermock issue 727跟踪Powermock从Javassist到ByteBuddy的不完整迁移。

现在,相反:为什么Mockito没有切换到Javassist而不是ByteBuddy?同样,我们没有直接答案,但the ByteBuddy tutorial expresses an opinion(在Javassist的“一般信息”下,强调我的):

该库附带一个编译器,该编译器接收包含Java源代码的字符串,这些源代码在应用程序的运行时期间被转换为Java字节代码。这非常雄心勃勃,原则上是一个好主意,因为Java源代码显然是描述Java类的好方法。但是,Javassist编译器在其功能中不与javac编译器进行比较,并且在动态组合字符串以实现更复杂的逻辑时允许容易出错。此外,Javassist附带了一个代理库,它类似于JCL的代理实用程序,但允许扩展类,并不限于接口。 Javassist的代理工具的范围在其API和功能方面同样受到限制。

简而言之:有轶事理由怀疑Javassist的安全性/功能/稳定性。 Mockito不需要Javassist的功能,所以它可以直接从cglib迁移到ByteBuddy。 PowerMock确实需要Javassist的功能,而且将PowerMock迁移到ByteBuddy的努力已经停滞不前。

© www.soinside.com 2019 - 2024. All rights reserved.