2014-06-16

mvn compile 無故發生 [ERROR] COMPILATION ERROR

自己造的孽還是得自己解,自己的蠢只有自己懂,為什麼呢?因為蠢到 google 上找不到解答。

已經一段時間了,使用 mvn compile 時總是發生 [ERROR] COMPILATION ERROR,詳細訊息是說找不到某些 class,但是專案裡真的有這些 jar 檔啊,不然 Eclipse 怎麼會過呢?

但是這問題只發生在 target 目錄空空的時候,只要在 Eclipse 裡執行過 Project > Clean...,就會在 target 目錄產生一些檔案,這時再執行 mvn compile 就不會有問題,真是奇怪(心裡的os:Eclipse 幫我產生了一些 mvn 生不出來的東西,以及原來有些東西 Eclipse 產生後,mvn 會借來用)。

在昏沉的禮拜一下午,突然找到原因了,兇手只有一個,但出現在兩個地方,第一個是 Maven 的 dependency scope,第二個是在 Maven Repository 裡沒有的 jar 檔。

Maven 的 dependency scope

因為有些 jar 檔在寫程式的時候用不到,但系統執行時會用到,比如像是 JDBC Driver 或者透過 Spring 將 Java 物件轉成 Json 的 jackson,這些 jar 檔我在 pom.xml 裡會將其 scope 設成 runtime,表示說 compile 不需要,但是要包到 war 檔裡。
<dependency>
 <groupId>org.codehaus.jackson</groupId>
 <artifactId>jackson-mapper-asl</artifactId>
 <version>1.9.13 </version>
 <scope>runtime</scope>
</dependency>
這裡的兇手就是 jackson,因為一開始在程式裡不會用到,後來為了要擋掉一些 Java 物件不要產生 Json,所以用了 jackson 的一些 annotation,依照我的認知,scope 為 runtime 的 dependency 不會出現在 Eclipse project classpath 裡,Eclipse project 應該 reference 不到 jackson 的 annotation class,但是卻 reference 到了(這是解決問題的線索),因此沒有察覺到 pom.xml 裡的 scope 還是 runtime,也就在 mvn compile 時掛掉了。

這邊有一些特別的點要指出來:
  • mvn compile 找不到 scope 為 runtime 的 jar,合理
  • 但是透過  m2eclipse 這個 Eclipse plugin 產生的 Eclipse project 設定檔,卻可以在開發時找到 scope 為 runtime 的  jar,不合理。
因為不合理的 m2eclipse 造成合理的 mvn compile 出錯,只要將 scope 改用 compile 或者拿掉 scope 不用(預設值為 compile),就可以了。

Maven Repository 裡沒有的 jar 檔

請先參考在 Maven Repository 找不到的 jar 檔?,就可以知道遇到 Maven Repository 沒有的 jar 檔時,應該手動安裝到自己本機的 Repository。

但是,我是懶惰的工程師,想說只有這個專案才會用到這個 jar 檔,裝了其他案子也不會用到,而且不是我裝就好,其他工程師也要裝,就取巧將 jar 直接放到 WEB-INF/lib 裡,然後在 Eclipse 裡直接 reference 過去,就這樣,報應就來了,mvn compile 有意見。

只要乖乖用 mvn install 將 jar 檔放到本機的 Repository,同一個專案的工程師都要,除非公司裡有裝 Maven Repository Server,這樣就沒事了。
---
---
---

沒有留言:

張貼留言