2011年10月11日

解決 Grails Maven 套件衝突問題

Grails 的 BuildConfig.groovy 可以很容易設定網站專案的「相依套件」,這個特性來自 Groovy 的 GrapeGradle ,讓 Java 及 J2EE 專案需要的 JAR 檔,可以從 Maven Repositories 自動取得,省去手動下載、維護 lib 及相依性問題的麻煩。

舉例來說,當 Grails 專案需要使用「mysql-connector-java (ConnectorJ)」連線到資料庫時,不必再去 MySQL 網站下載 *.jar 檔案、設定 CLASSPATH 等,只要在 BuildConfig.groovy 增加一行 runtime 的 Grab 設定,並且可以指定版本編號,日後要升級成新版也只需要更改此版本編號。

dependencies {
    runtime 'mysql:mysql-connector-java:5.1.16' //for mysql datasour
}

Grails 並不會將相依的 *.jar 直接放到專案的資料夾下,而是放在 HOME 的 .grails 資料夾。對於使用 SVN / GIT 版本控制系統的專案來說,這是個相當實用的作法。專案資料夾不必包含網路下載即可取得的 *.jar 檔案,更有效利用版本控制系統的儲存空間,日後要 clone 到別部開發機器、伺服器也更快(在別台機器執行 Grails 時會也會自動下載相依套件檔案)。

但是 Java 的自動化套件管理的機制,並不是每次都那麼管用,有時候會遇到套件衝突的問題。

有兩種設定方式,可以解決衝突的問題。

第一種是在 runtime 的 closure 中增加 transitive = false ,停止自動使用相依套件的功能。但是這麼一來,就必須增加其他 runtime 設定將相依套件補齊。

第二種方式是用 excludes 排除出包的套件,如果不載入這些有衝突的套件,會影響主套件的必要功能,同樣必須增加 runtime 將套件補齊,但至少需要增加設定的數量會比關閉 transitive 少得多。

例如 jrst 1.4 的套件,依賴的 fop 、 saxon 就會造成 Grails 啟動失敗,因此使用 excludes 將有問題的套件排除。

Error executing script TestApp: loader constraint violation: when resolving overridden method "org.apache.tools.ant.helper.ProjectHelper2$RootHandler.setDocumentLocator(Lorg/xml/sax/Locator;)V" the class loader (instance of org/codehaus/groovy/grails/cli/support/GrailsRootLoader) of the current class, org/apache/tools/ant/helper/ProjectHelper2$RootHandler, and its superclass loader (instance of ), have different Class objects for the type org/xml/sax/Locator used in the signature (Use --stacktrace to see the full trace)

runtime ('org.nuiton.jrst:jrst:1.4') {
    //transitive = false
    excludes "fop", "saxon"
}

每次安裝 Grails Plugins 或增加 dependency 設定後,必須要做一次完整的 test  ,才能及時處理套件衝突問題。

Happy Grails !!!

沒有留言:

張貼留言

lyhcode by lyhcode
歡迎轉載,請務必註明出處!