2020年10月27日 星期二

Maven - 引用本地端的 jar

這篇文主要來紀錄我使用 Maven 引用本地端 jar 檔的經驗。

在使用 Maven 時,如果想要加入到 library 的 jar 檔在 Maven 的 Repository 找不到、

例如:

  1. 因為某些授權的原因,jar 檔的作者不願意將之放到 Maven Repository 上面,
    或就是沒有人把其 jar 檔放到 Maven Repository 上面。
  2. 可能 jar 檔是來自於合作的第三方,例如跟公司合作的夥伴提供的專屬 jar 檔。
  3. 或是本來原本官方的 jar 檔,有被自己以手動的方式做二次修改的 jar 檔 ,可能是為了相容問題或修正某些官方 bug,例如:Proxool + MS SQL Server DB Driver的相容问题 (參考:
    JAVA+ Proxool+ SQLserver 2008 “signer information does not match signer information of other classe...
    Proxool+SQLserver2008(sqljdbc4.jar) integration problem
  4. 自己寫的,例如公司內部用的 jar 檔,或是想要把舊專案轉成 Maven 時,因年代已久無法考證 jar 檔來原,所以乾脆直接繼續拿來用的 jar 檔。

這時我們就必須要引用本地端 (local) 的 jar 檔,

Maven 大概有幾種作法:

  1. 在 pom.xml 使用 <scope>system</scope> 和 <systemPath> 來引用本地 jar 檔檔案路徑
  2. 將本地 jar 檔放到 local repository (使用命令列指令)
  3. 將本地 jar 檔放到 local repository (在 pom.xml 中加入設定)


首先先講我在實務上希望的需求是:

  1. 能夠在 pom.xml 中容易地看出哪些是自訂的 local jar dependency。
  2. 能夠看得出及容易找出 local jar 檔放在哪裡。
  3. 能夠在不下命令列指令的情況下成功地匯入 jar 檔到 local repository。
  4. 能夠跟 IDE 配合,例如: Eclipse Maven Plugin + Tomcat 

再來在以下分述這三種作法及我實務上的例子,及我最後的選擇偏好:


1. 在 pom.xml 使用 <scope>system</scope> 和 <systemPath> 來引用本地 jar 檔檔案路徑

第一種方法 (稱為 System Dependencies) 在使用上非常簡單,直接在 pom.xml 上指定 local jar 檔的檔案路徑,

例如:

<dependency>
        <groupId>myGroupId</groupId>
        <artifactId>myArtifactId</artifactId>
        <version>1.0.0</version>
	<systemPath>D:\myJar.jar</systemPath>
	<scope>system</scope>
</dependency>

其中 <systemPath> 中也可使用用一些 Maven 自己的參數,例如表示專案路徑的 ${basedir}

此方法有幾個缺點:

  1. Maven 官網說 <scope>system</scope> 的用法 (System Dependencies)已經 deprecated 了 (來源)
  2. 在要使用 maven 指令部屬專案時,例如要產生 war 檔時, mvn clean install 產生出的 war 檔裡並不會把用 System Dependencies 設定的 local jar 檔包進生產的專案中。
  3. 如果使用 Eclipse Maven plugin + Tomcat 來開發,用 System Dependencies 設定的 local jar 檔不會被部屬至 server 上 (例如:  C:\Users\xxxUser\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\xxProject\WEB-INF\lib)


2. 將本地 jar 檔放到 local repository (使用命令列指令)

此方法是使用 Maven 的指令直接將本地端的 jar 檔放進 local repository 中,命令如下 (大括弧 {} 中的值可自由填寫):

mvn install:install-file -Dfile={本地端 jar 檔的檔案位置} -DgroupId={自訂的 group id} -DartifactId={自訂的 artifact id} -Dversion={自訂的 version}

例如:

mvn install:install-file -Dfile=D:\myJar-1.0.0.jar -DgroupId=myGroupId -DartifactId=myJar

-Dversion=1.0.0

注意 jar 檔的檔名要改成符合 maven 格式,就是 artifactId-version 這種格式。

執行完命令後,可以到自己本地上的 local respository (通常位置在C:/Users/xxxUser/.m2/repository) 去看是否有成功匯入 jar 檔。

最後在 pom.xml 中加入引用 jar 檔的設定如下:

<dependency>
          <groupId>myGroupId</groupId>
          <artifactId>myArtifactId</artifactId>
          <version>1.0.0</version>
</dependency>


不過個人認為這種方法有一個缺點,

就是如果今天我們換了一台電腦或換了一個開發者要開發時,

必須要對 local jar 檔再一次執行上述的命令例指令以匯入 jar 檔 local repository,

並且單看 pom.xml 很難辨認出哪個 dependency 是使用了自訂的 local jar 檔。

對比我上述的需求,此方法:

  1. 無法在 pom.xml 中容易地看出哪些是自訂的 local jar dependency (除非把命令列指令存起來,再對照去找 local jar 檔位置)。
  2. 單看 pom.xml 看不出 local jar 檔放在哪裡 (除非例如把要下的命令列指令放到 project 中的某一個 file 上)。
  3. 需下命令列指令來匯入 jar 檔到 local repository。
  4. 能夠跟 IDE 配合,例如: Eclipse Maven Plugin + Tomcat 


3. 將本地 jar 檔放到 local repository (在 pom.xml 中加入設定)
補充:不確定是不是 Maven 3 版本以上才需要,發現除了本地 jar 檔,還需要再放一個本地 pom 檔 (除了附檔名,檔名跟本地 jar 檔一樣)

此方法是我目前最喜歡的方法,此方法跟第二種方法一樣,

都是把本地 jar 檔放到 local repository 中,不過差在不是執行命令列指令,

而是把要的設定寫在 pom.xml 中。

首先我們要在 pom.xml 中,設定自訂的 repository,例如:

<repository>
	<id>localLibRepository</id>
	<name>localLibRepository</name>
	<url>file:${basedir}/localLibRepository</url>
</repository>

其中 ${basedir} 為 Maven 的參數,代表專案的根目錄位置,

localLibRepository 為我自己建立的資料夾,用來存放 local jar。


設定好後,接著要來把 local jar 檔放到相應的位置去,

首先像上述第二種方法一樣,把 local jar 檔命名成 maven 的格式,例如: 

myArtifactId-1.0.0.jar

然後仿照 Maven Repository 的檔案路徑格式,即 

{repositoryPath}/{groupId}/{artifactId}/{version}/{jarFileName}

的規則建立資料夾 (如同 java 的 package 一樣,如 com.xxx.yyyy,應為 com, xxx, yyy 三個資料夾),並將 local jar 檔放到正確的位置上,例如:

D:\myProject\localLibRepository\myGroupId\myArtifactId\1.0.0\myArtifactId-1.0.0.jar

接著在同一個位置增加 pom 檔,例如:

D:\myProject\localLibRepository\myGroupId\myArtifactId\1.0.0\myArtifactId-1.0.0.pom

內容範例如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>myGroupId</groupId>
  <artifactId>myArtifactId</artifactId>
  <version>1.0.0</version>
</project>

最後如第二種方法一樣,在 pom.xml中引入 local jar 檔的 dependency,例如:

<dependency>
          <groupId>myGroupId</groupId>
          <artifactId>myArtifactId</artifactId>
          <version>1.0.0</version>
</dependency>

之所以我最後選擇這個方法的原因是,它完全符合我的需求:

  1. 比較能夠在 pom.xml 中容易地看出哪些是自訂的 local jar dependency
    (對照 pom.xml 中自訂 repository 的設定,打開 repository 的資料夾即可得知)。
  2. 能夠看得出及容易找出 local jar 檔放在哪裡 (看 pom.xml 中即可得知自訂 repository 的位置)。
  3. 能夠在不下命令列指令的情況下成功地匯入 jar 檔到 local repository。
  4. 能夠跟 IDE 配合,例如: Eclipse Maven Plugin + Tomcat 


參考資料:

  1. 3 ways to add local jar to maven project
  2. Adding dependencies to local .jar files in pom.xml
  3. How to include local jar files in Maven project [duplicate]
  4. Maven私服上传pom和jar实操

沒有留言 :

張貼留言