簡體   English   中英

ClassLoader加載類的先前版本-Java

[英]ClassLoader loads previous version of classes - Java

我編寫了一個插件,該插件獲取類文件列表(由編譯Java項目產生)作為輸入,並運行與這些類相關的測試用例。 我使用類加載器加載類,並使用JUnitCore()運行測試用例。 下面的代碼運行良好,並且為輸入類運行時沒有問題。

Class<?> clazz =  Class.forName(className);     
Request request = Request.aClass(clazz);   
Result result = new JUnitCore().run(request);

但是,在我的程序中,對於類似的類,上面的代碼應運行數千次。 為了簡單起見,假設我們只有一個類,首先編譯該類,然后如果沒有編譯器錯誤, 則將其復制到插件的bin目錄中 ,然后在該目錄上調用我的程序並檢查它是否通過了所有測試用例。

在下一次迭代中,原始源代碼會自動更改,然后進行編譯;如果沒有編譯器錯誤,則將其復制並再次運行測試用例。 該過程可以運行數千次以獲得所需的結果。 [有時甚至幾個小時]

但是,問題在於類加載器使用編譯器類的第一個版本,並且在下一次迭代中它不會加載新版本,而仍使用前一個版本。 我發現,如果在每次迭代中在復制指令之前添加Thread.sleep(1000) ,那么它都能找到正確的版本。

首先,為什么我需要在復印之前暫停而不在復印之后暫停? 我希望在類加載器要加載文件之前,可能不會在復制過程中最終確定文件,並且類加載器使用以前的版本。 但是,正如我所說,當我在復制前添加暫停時,它可以正常工作,當我在復制后添加暫停時它使用以前的版本。

其次,在程序中使用睡眠不是一個好主意。 在最好的情況下,我的插件可能會工作數小時才能找到所需的結果,如果我想在每次迭代中添加睡眠,那么要花幾天的時間才能得到結果。 因此,我更喜歡不睡覺的解決方案。 如果有人知道如何在沒有Thread.sleep的情況下解決上述問題,請告訴我。

我找到了解決方案。 實際上,在更改程序后,我首先刷新項目,然后復制文件。 但是,問題在於JDT不會在復制之前重新編譯和重建索引。 所以我需要等待重建完成,然后再進行復制。 這就是為什么復制前Thread.sleep可以解決此問題的原因。 但是,更好的解決方案是在刷新項目時使用以下說明。

 try {
        project.refreshLocal(IResource.DEPTH_INFINITE, null); 

        IJobManager jobManager = Job.getJobManager();
        jobManager.join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
    } catch (CoreException | OperationCanceledException | InterruptedException  e) {
            e.printStackTrace();
    }

以上幾行解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM