我已經編寫了一個插件,它可以獲取類文件列表(從編譯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