Javassist:重新创建一个类 - 先删除,还是解冻()并修改?

时间:2013-06-26 14:43:54

标签: java classloader javassist bytecode-manipulation

我使用Javassist创建一个类。在测试套件中,当第二个测试尝试创建同一个类时,它会在pool.makeClass( ... )失败,因为该类已被冻结(即已经通过toClass()创建。

克服这个问题的方法是什么?理想情况下,第一个测试应该以某种方式删除类 - 也许从类加载器中卸载 - 但是当我读到in JLS时,卸载操作是不可靠的。

因此,或许解决方法是检查类创建代码是否存在,如果存在,defrost()它,删除所有成员等,并重新创建它。

还有其他想法吗?

或者有没有可靠的方法通过Javassist删除该类?

2 个答案:

答案 0 :(得分:4)

您无法从ClassLoader卸载单个班级。如果一个类及其ClassLoader变得无法访问,则可以卸载该类,但由于每个类都引用其加载器,这意味着此加载器加载的所有类也必须变得无法访问。

但您可以使用不同的ClassLoader(重新)创建该类。好吧,正式地说它是一个具有相同名称(可能是相同的字节代码)的不同类。如果在测试用例中执行的代码在堆中没有引用,则在测试之后可能会收集ClassLoader及其类。

答案 1 :(得分:0)

我遇到同样的问题,我这样解决了,可能无法申请你的测试用例:

使CtClass成为类的私有静态变量。

创建一个检查是否已构建CtClass的方法。  如果没有构建CtClass,则调用构建它的方法,否则返回该CtClass。

让所有测试都使用新方法。

因此,如果您有N Test,只需要第一个尝试构建CtClass,其余的将具有静态CtClass变量。