我已经编写了一个插件,它可以获取类文件列表(从编译Java项目产生)并运行与这些类相关的测试用例。我使用类加载器来加载类,并使用JUnitCore()来运行测试用例。下面的代码工作正常,并且在运行输入类时没有问题。ClassLoader加载以前版本的类 - Java
Class<?> clazz = Class.forName(className);
Request request = Request.aClass(clazz);
Result result = new JUnitCore().run(request);
但是,在我的程序中,上面的代码应该运行上千次的类似类。为简单起见,假设我们只有一个类,第一步编译类,然后如果没有编译器错误它被复制到插件的bin目录中,然后调用我的程序并检查它是否通过所有测试用例。
在下一次迭代中,原始源代码会自动更改,然后编译它,如果没有编译器错误,则复制并再次运行测试用例。这个过程可以运行上千次以获得期望的结果。 [在某些情况下甚至是几小时]
但是,问题在于类加载器使用编译器类的第一个版本,并且在下一次迭代中它不加载新版本并仍使用前一个版本。我发现如果我在每次迭代中添加一个Thread.sleep(1000)之前复制指令,那么它可以找到正确的版本。
首先,为什么我需要暂停之前复制和不是复制后?我希望文件在类加载器要加载它们之前的复制期间没有最终完成,并且类加载器使用以前的版本。但是,正如我在复制之前添加暂停时所说的那样,它可以正常工作,并在复制后添加暂停时使用以前的版本。
二,在我的程序中使用睡眠不是好主意。我的插件在最好的情况下可能需要几个小时才能找到想要的结果,如果我想在每次迭代中添加睡眠,那么需要几天才能得到结果。因此,我更喜欢没有睡眠的解决方案。请让我知道是否有人知道如何在没有Thread.sleep的情况下复制上述问题。
ClassLoader实际上并不使用类的“previos”版本,它在第一次加载时使用类的第一个版本。如果班级被加载,它将不会被新的替换。你必须做一些小小的魔法才能加载新版本。这些问题已经被问到,使用搜索。 – 2014-09-20 11:49:59
[Create new ClassLoader to reload Class](http://stackoverflow.com/questions/9819318/create-new-classloader-to-reload-class) – Joe 2014-09-20 11:55:08
当我添加一个睡眠,然后它使用正确的版本。 – user3601784 2014-09-20 11:56:02