大家好,這裡是收到一顆日本青森縣產的蘋果的小編過路君子
聽說青森的蘋果很好吃,送給小編蘋果的那個人一直說很好吃很好吃。
很多時候我們必須跟其他人一起合作撰寫 Java 程式,這時候對方可能就會提供以下的 Maven 資訊:
<groupId>this.is.the.parent.pom</groupId> <artifactId>dependency-info</artifactId> <version>3.7.5</version>
這時候我們就不能像以前只有自己寫的時候一樣,pom.xml 內想寫什麼就寫什麼。
必須依照對方所提供的 pom.xml 來做設定,特別是 <version> 這個屬性,因為在一個專案內,所使用的套件如果版本不一致可能會對整個專案帶來一些阻力。
所以我們第一步就是將對方的 pom.xml 引用進我們原來的 pom.xml。
<!-- own pom.xml file --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>that.is.our.self.pom</groupId> <artifactId>myCode</artifactId> <version>1.0.3</version> <packaging>jar</packaging> <!-- Put here that other side pom.xml dependency information --> <parent> <groupId>this.is.the.parent.pom</groupId> <artifactId>dependency-info</artifactId> <version>3.7.5</version> </parent> <!-- We must add other side repository url, otherwise we can't get the parent pom.xml --> <repositories> <repository> <id>maven-public</id> <url>http://127.0.0.1/repository/maven-public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </project>
這時候的 dependencies 寫法就有兩種,第一種是不用寫,第二種是要寫,但是不提供版本資訊。
至於要採用第一種還是第二種的寫法,還是看 parent pom.xml 如何撰寫,所以我們分別來看一下兩種的差異:
第一種:不用寫
這時候的 parent pom.xml 內的 <dependencies> 資訊並沒有任何的特別,例如:
<!-- parent pom.xml --> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.9.2</version> </dependency> </dependencies>
那這時只需要我們像上方的 pom.xml 一樣,以<parent></parent>
的方式將對方的 pom.xml 引入到我們的 pom.xml 內,在打包的時候就會自動一起打包進去。
如果使用這種方式就代表寫 parent pom.xml 的人認為每個使用到此 parent pom.xml 的工程師都會用到 dependencies 裡面所有的包,所以就算今天我們的程式內並未使用裡面的包,依舊會被一起打包進去我們的 .jar 或 .war 內。
而且我們還沒辦法阻止,所以容易造成打包的時間過長或是過於冗贅的問題。
第二種:要寫,但是不提供版本資訊
這時候的 parent pom.xml 內就跟我們平常在寫 pom.xml 長得不一樣了,如下:
<!-- parent pom.xml --> <dependencyManagement> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.9.2</version> </dependency> </dependencies> </dependencyManagement>
沒錯,這個多出來的<dependencyManagement></dependencyManagement>
是只會用在這個場合內的,可以理解成定義在此區塊內的所有 dependency 資訊僅僅只是定義而已。
在打包的時候 Maven 並不會主動將定義在此區塊內的 jar 檔打包進 jar 或 war 檔內,所以還是會出現找不到依賴包的錯誤。
這時候我們就必須手動在我們自己的 pom.xml 內寫入依賴資訊,但不用提供依賴包版本,Maven 會自動抓取 parent pom.xml 內所定義的版本來使用。
<!-- own pom.xml file --> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> </dependency> </dependencies>
那如果我們依舊在這之內使用了<version></version>
寫入了版本資訊,那我們的 Maven 在打包的時候依舊會使用我們所寫的版本,那......不就失去了 parent pom.xml 的作用了?
那我們要確認提供此 parent pom.xml 的人是否有定義我們要用的依賴包資訊也很簡單,首先我們同樣先將依賴資訊加入我們的 pom.xml,但先不加入 version 資訊。
如果成功打包那就代表對方的 parent pom.xml 有定義我們所需的依賴包資訊,反之如果出現以下訊息,則代表對方並未定義我們所需使用依賴包資訊:
[ERROR] 'dependencies.dependency.version' for com.github.bumptech.glide:glide:jar is missing. @ line 42, column 15
@
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project that.is.our.self.pom:myCode:1.0.3 (/home/user/myCode/pom.xml) has 1 error
[ERROR] 'dependencies.dependency.version' for com.github.bumptech.glide:glide:jar is missing. @ line 42, column 15
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
這時候再將版本資訊添加進去即可,那至於要不要通知 parent pom.xml 的管理員加入你所使用的依賴包選項則就依照各位的狀況來斟酌了。
順帶一提,plugins 也有對應的 tag<pluginManagement></pluginManagement>
可以使用,其用法跟上面的 dependencyManagement 一模一樣,只是一個放在 dependencies 之前,而另一個放在 plugins 之前。
代表的意義完全一樣,用來定義所使用的 plugins 版本資訊。
後記
其實後來發現 Maven 對於 parent pom.xml 所繼承的資訊其實還滿寬鬆的,連 distributionManagement 或是 repositories 所定義的資訊都可以繼承下來。
換句話說,如果有個依賴包在 Maven 預設的資料庫內沒有的話,其實是可以寫道 parent pom.xml 內,這樣所有使用到的工程師的 pom.xml 就會自到我們所設定的遠端資料庫去下載。