Grails 和 Maven:一段不便的結合

工程 | Dave Syer | 2007年7月14日 | ...

引言

Grails 似乎發展勢頭越來越強勁,而且看來它確實“站穩了腳跟”,正如他們所說。我對將它的應用範圍稍微擴充套件到 Web 應用領域之外很感興趣。如果你瞭解我在 Spring Batch 方面的工作,你大概就能猜到這可能會把我帶向何方。但在這篇文章中,我只想分享一些我在 Grails 應用的基本、底層部署和構建方面的一些經驗。

我對 Maven 2 既愛又恨,我正在學習喜歡 Grails,但不幸的是,兩者並不能很好地協作。如果能看到更緊密的整合將會非常棒。Maven 並不總是我們想要的樣子,但有些方面確實讓它很有價值。它是一種標準(無論你愛它還是恨它),所以當我從某個地方下載一個專案時,我已經知道如何構建它,它的依賴是什麼,以及文件在哪裡。Grails 也有一些相同的特性,事實上它包含了自己基於 Groovy 指令碼 Ant 的相當複雜的構建工具。也許存在一箇中間道路,讓我們能夠兼得兩者的優點?

我也知道該領域的一些其他活動,希望我們能圍繞某個方向 объединять 一下(也許可以從本論壇和 Grails JIRA 的討論中獲得啟發)。例如,請看 Frederick Verbist 的部落格和 Arnaud Heritier 的 maven 整合專案(目前剛剛起步)。Grails 團隊傳統上對 Maven 印象不佳(例如,參見此處),但我與 Graeme Rocher 聊過,他對建議持開放態度,所以我希望我們在這裡能取得一些進展。

使用 Maven 為 Grails 構建原型依賴管理

本著朝著 maven 整合邁出簡單步驟的精神,我附上了一組 poms,它們(大致)描述了我在 Grails 0.5.6 中瞭解到的 Grails 依賴結構。如果您遇到問題,請忽略或更改 Spring 版本號 - Grails 0.5.6 使用 Spring 2.0,但我正在進行的專案需要 2.1。Graham 說 Grails 可能無法與更高版本的 Spring 正常工作,因此您的實際情況可能有所不同。這就是 Maven 的美妙之處,對吧?您可以明確地、傳遞地看到專案依賴,並且可以以您控制的方式調整它們,以滿足您自己的需求和對風險的承受能力。

Maven 使用者附註:依賴外掛比以前工作得更好了,您可以使用“mvn dependency:tree”打印出依賴樹。這僅適用於全新的外掛,因此請確保 apache-snapshots 倉庫在您的外掛倉庫中。


<pluginRepositories>
	<pluginRepository>
		<id>apache-snapshots</id>
		<url>http://people.apache.org/maven-snapshot-repository</url>
	</pluginRepository>
</pluginRepositories>

這比必須構建整個站點並檢視依賴報告方便得多,而我以前經常這樣做。

一個 POM,一個 POM,我的王國換一個 POM...

當一個神志不清的 Maven 使用者首次面對 Grails 專案並試圖理解它如何協同工作時,這是他的吶喊。希望我們在此能展示如何安撫這位可憐的神志不清的個體。為此,我們將介紹一些簡單的步驟,為現有 Grails 專案建立一個 Maven 專案。

在隨附的沙盒存檔中,有三個 poms,每個都在自己的專案中

  • base = 與 Web 應用無關的依賴項的基礎 POM。我在這方面相當寬鬆(例如包括 Spring Weblfow)。目標是僅憑這些依賴項就應該能夠啟動 grails console。
  • web = 為 Web 應用建立 WAR 檔案所需的額外依賴項。這可能在一定程度上取決於平臺,但此處包含的依賴項將在 Servlet 2.4 容器(如 Jetty 5.1,這是 Grails 傳統上使用的)中工作。
  • launch = 僅用於在獨立或開發環境中啟動 Web 應用的 Jetty 和 JSP 依賴項

要安裝 Grails poms,您無需手動將任何工件新增到本地倉庫。還有一些“奇怪的”(我在任何標準的公共倉庫中都找不到),我已經將它們包含在“spring-ext”倉庫中(在 pom 中定義)。如果您連線到網際網路,它應該可以直接工作。

執行樣本的先決條件

您需要 Maven (2.0.*) 和 Grails (0.5.6) 來執行樣本應用。我使用的是 Maven 2.0.7。“grails”和“mvn”啟動指令碼需要放在您的 PATH 中,並且您需要定義 GRAIL_HOME 環境變數來執行 Grails(標準安裝程式)。

測試專案

還有一個測試專案,它使用上面的 poms 來管理一個 Web 應用。我決定堅持使用 Grails 的目錄佈局。Graham 告訴我,web-app/WEB-INF 中幾乎所有“可變”內容都計劃在 Grails 1.0 中移除,所以我認為使用 Grails 規定的結構是最好的前進方向(最不容易脆弱,易於其他 Grails 開發者理解)。

從 Grails 命令列啟動

$ cd test
$ mvn package
$ grails run-app

要向測試專案新增額外的依賴項,只需將它們新增到 pom 中並重復此操作(或在 Eclipse 中什麼都不做,見下文)。Maven 是不是很棒?

請注意,在專案 pom 中,Grails 依賴項的範圍是 scope=provided。這意味著它們會包含在 Maven 和 Eclipse 的 classpath 中,但不會包含在任何 Maven 打包中(如果已實現)。

僅限 Eclipse 使用者

測試專案還包括 Eclipse 專案工件 - 使用 Maven Eclipse 擴充套件以獲得最佳結果 (http://m2eclipse.codehaus.org/update-dev/)。使用此 Eclipse 擴充套件,您將能夠在工作空間中處理其他 Maven 工件專案,如果它們是 Grails 專案的依賴項,它們將被自動新增到 classpath 中,並在您進行更改時動態更新。

如果您不使用 Maven Eclipse 擴充套件,那麼您可能可以使用 Eclipse Maven 外掛(也稱為 maven-eclipse-plugin)。使用“mvn eclipse:eclipse”更新 .classpath 並重新整理,然後應該就可以了,但無法自動與 Eclipse 其他專案中的更改同步。

您需要先從命令列執行一次“grails package”(僅執行一次)

$ cd test
$ grails package

這將為您生成一個 web.xml,並複製和過濾 grails-app/conf 中的一些屬性檔案。顯然,長期的前景是 web.xml 將是 web-app/WEB-INF 中唯一生成的檔案(這樣每個人的原始碼控制系統中就只有一個 svn:ignore)。

在 Eclipse 中,您可以匯入測試專案。然後可以執行...並從 Java 應用中選擇“test”啟動器。您可以除錯,並且可以動態更改程式碼,無論是 Grails 應用本身還是其依賴的專案中的程式碼。

下一步

我附帶的工具還有一些缺失/不舒服的地方。它們仍在很大程度上處於開發中。如果有人試用它們,無疑會提出改進的建議。請在此處或在 Grails JIRA 上發帖。

以下是一些已知問題或令人惱火之處

Grails 打包中的重複 Jar

Grails 核心的一些依賴項可能與 poms(Grails poms 或專案 pom)中的依賴項不同或名稱不同。當您執行“grails package”時,它會將 GRAILS_HOME/lib 中的 jar 檔案複製到 web-app/WEB-INF/lib 中,並且無法阻止重複。例如,只要 Grails 不使用完整的 jar 名稱,您就會在 WEB-INF/lib 中看到重複項。

這個問題因為 Maven 依賴外掛目前不允許我們排除 scope=provided 的依賴項而更加複雜,因此當您執行“mvn package”時,所有 Grails 依賴項最終都會出現在 ./lib 中。這對於 Grails 開發者來說並不方便,因為它們通常是從 GRAILS_HOME/lib 中複製的。理想情況下,這種衝突將在我們真正實現 Maven-Grails 整合之前得到解決。

缺少其他 Maven 生命週期階段

這個簡單的演示為 Grails 提供了一個 clean 和一個 package 生命週期增強。我們希望能夠使用 Maven 為我們完成更多的開發和持續整合工作。

例如,我們希望從 Grails 專案佈局構建一個 WAR 檔案。用 Ant 和 Maven 實現這一點不會太難。理想情況下,它應該作為 Maven 外掛實現——這與 Arnaud 的專案非常相似,所以我希望他能取得一些進展,同時也希望他能從這裡的經驗中學習。

其他有用的生命週期階段也缺失了。例如,樣本中無法透過 Maven 驅動測試。

Grails 打包週期

Grails 和 Maven 各有其自己的“打包”週期。通常 Grails 的打包只需發生一次(在兩次 clean 之間),但這仍然很麻煩,必須記住要執行它。

Eclipse 的 Groovy 外掛

在 .groovy 原始碼中有語法高亮很好,但除此之外,Groovy 外掛似乎只會礙事。這與 Maven 或 Grails 都沒有關係,但已知它會給其他 Grails Eclipse 使用者帶來問題。例如,如果您編輯控制器或服務,很可能會看到一個令人不快的警告訊息,詢問您是否要終止應用程式。Groovy 外掛檢測到了更改,而 Eclipse 無法處理 classpath 的更改。但 Grails 可以,所以通常您可以點選“繼續”按鈕。但並非總是如此。在專案屬性中關閉 Groovy 編譯是安全的,但這會失去對非 grails-app 類的動態編譯。
附件再次附上:點選此處

訂閱 Spring 新聞通訊

訂閱 Spring 新聞通訊,保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速前行。

瞭解更多

獲取支援

Tanzu Spring 透過簡單的訂閱提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視全部