2014-11-25 71 views
2

我有一個註釋處理器,用於查找包含特定註釋的文件。處理器的輸出是一個文件,引用每個這樣的註釋文件。當只有一個子集被編譯時,註釋處理器需要處理所有文件,但是如何?

例如,如果類Xÿ,和Ž包含註釋@foo,則@foo處理器將產生像一個文件:

class FooFiles { 

    Class[] getFooClasses() { 
    return new Class[]{X.class,Y.class,Z.class}; 
    } 

} 

這如果我執行mvn clean compile,則工作正常,因爲所有類都被編譯並傳遞給註釋處理器。

但如果類是最新的,而我只修改一個(說X類),那麼mvn compile將執行增量構建,並且因爲只有X類被編譯,那麼只有X類被傳遞到標註處理程序,生成的文件是:

class FooFiles { 

    Class[] getFooClasses() { 
    return new Class[]{X.class}; 
    } 

} 

這是不好的。

我正在使用maven與maven-compiler-plugin版本2.5.1,這似乎做增量編譯。

如果我將maven-compiler-plugin更新爲版本3.1,則任何一個文件的更改都會導致編譯所有文件,並且不會出現此問題(儘管只有一個文件發生更改時編譯所有文件可能不是此處的解決方案,其他開發人員會因爲一個文件更改而需要從頭開始重新編譯帶有10K +文件的模塊時纔會投訴)。我曾嘗試在插件的配置中將useIncrementalCompilation選項設置爲true,但似乎無論如何重新編譯所有文件。

我修改了我的註釋處理器,以便它不覆蓋任何現有的生成文件。這意味着在clean之後,生成包含X,YZ參考文獻的正確供應商文件。但是,如果只是X發生更改,則不會生成新的提供程序文件。這允許增量編譯,但是在必要的時候記住要做clean

我不確定這裏是否有一個通用的解決方案,但我總是問。我想我真正想要的是註釋處理器在compile階段之後通過target/classes目錄運行。我可能需要爲此寫一個maven插件。

回答

1

有一個bug in maven-compiler-plugin version 3.1. that causes incremental builds to fail。無論如何,目前最新的版本是3.2。

這很糟糕。

只是因爲它打破了你當前的處理器。正如你自己所指出的那樣,這並不是所有時間重建一切的最佳解決方案。更好的方法是支持增量構建。這將使構建更快,並且您的處理器與更多編譯器,IDE和構建工具兼容。你可能需要一種新的方式來處理你的註釋類。

這是一個想法,你可以去支持增量構建。

您不是像FooFiles那樣收集所有類在一個地方,而是生成一個資源文件,該文件將列出您的所有類,然後添加您在增量構建中遇到的每個帶註釋的類。每當需要使用FooFiles時,您都可以從該資源文件讀取類。您還需要刪除已刪除或未註釋的列表中的類。

如果你的處理器比較複雜,它不會那麼簡單,但我的一般方法仍然可以工作。您也可以爲每個註釋類生成一個類,如果屬性文件不夠,它會在某處動態註冊它自己。

+0

我喜歡用它們中的類名列表生成資源文件的想法。當帶有註解的類被編譯時,它確保它的名字在該文件中。提供者類然後加載資源文件並創建那裏列出的類的實例。唯一的問題是它不會處理從資源文件中刪除類名稱。如果註釋從文件中移除,註釋處理器將看不到註釋,並且它不會自行移除。除非有辦法知道哪些類已編譯但未由註釋處理器處理... – 2014-11-27 05:15:24

+1

我認爲,如果處理器支持所有註釋,即使註釋被移除時它也會始終使用,它可以工作。在處理器的每次執行中,您都應該能夠使用反射/鏡像API,並查看列表中的類和它們的註釋是否仍然存在。 tbh我從來沒有嘗試過這個。另外我不確定當你刪除一個類時,編譯/處理甚至會被所有的IDE調用。如果沒有,我想你需要在運行時檢查列出的類是否真的存在。 – Kapep 2014-11-28 19:28:50

+1

這可能會起作用,所以我會將其標記爲答案。不過,我認爲繞過註釋處理可能是更好的解決方案。我編寫了一個quick-n-dirty maven插件,用於處理targets/classes目錄中的類文件,使用註釋查找類,並將java文件生成到targets/generated-test-sources。這個插件在generate-test-sources階段運行。似乎有效且正確地工作,但我必須將註釋的保留策略從COMPILE更改爲RUNTIME。 – 2014-11-30 23:28:18