我使用Javassist创建一个类。在测试套件中,当第二个测试尝试创建同一个类时,它会在pool.makeClass( ... )
失败,因为该类已被冻结(即已经通过toClass()
创建。
克服这个问题的方法是什么?理想情况下,第一个测试应该以某种方式删除类 - 也许从类加载器中卸载 - 但是当我读到in JLS时,卸载操作是不可靠的。
因此,或许解决方法是检查类创建代码是否存在,如果存在,defrost()
它,删除所有成员等,并重新创建它。
还有其他想法吗?
或者有没有可靠的方法通过Javassist删除该类?
答案 0 :(得分:4)
您无法从ClassLoader
卸载单个班级。如果一个类及其ClassLoader
变得无法访问,则可以卸载该类,但由于每个类都引用其加载器,这意味着此加载器加载的所有类也必须变得无法访问。
但您可以使用不同的ClassLoader
(重新)创建该类。好吧,正式地说它是一个具有相同名称(可能是相同的字节代码)的不同类。如果在测试用例中执行的代码在堆中没有引用,则在测试之后可能会收集ClassLoader
及其类。
答案 1 :(得分:0)
我遇到同样的问题,我这样解决了,可能无法申请你的测试用例:
使CtClass成为类的私有静态变量。
创建一个检查是否已构建CtClass的方法。 如果没有构建CtClass,则调用构建它的方法,否则返回该CtClass。
让所有测试都使用新方法。
因此,如果您有N Test,只需要第一个尝试构建CtClass,其余的将具有静态CtClass变量。