我最近一直在恢復兩個專案,這些專案涉及基于 JNI(帶有本機庫的 Java)代碼。構建系統是遺留系統(基于 Makefile,而不是 Maven 或 Gradle),但考慮到專案的年齡(它們的出現早于 Maven),并且因為代碼的某些重要部分不是用 Java 撰寫的,這沒關系。
沒有計劃用 Maven 或 Gradle 配置腳本替換 Makefile(或配置)腳本(我繼承的構建系統作業正常,并且可能不會使用其他工具變得更簡單,因為這些軟體不是純 Java) .
但是,使用 Maven 安裝插件在 Maven 存盤庫中部署 jars(甚至使用其他工具構建)很簡單,并且使第三方代碼對它們的使用更加簡單,所以我采用了這種方式。
我可以讓一切正常作業,但我一直無法弄清楚為什么 Maven(或更具體地說,Maven 安裝插件)的行為如此,這似乎使事情變得比他們需要的更復雜。最有可能的是,我缺乏對 Maven 的行為或 Java 鏈接系統的理解。
這是問題所在:要安裝 jar 及其本機庫,可以使用以下命令。
mvn install:install-file -Dfile=$(jarFile) -DgroupId=$(groupId) -DartifactId=$(artifactId) -Dversion=$(libraryVersion) -Dpackaging=jar
mvn install:install-file -Dfile=$(nativeLibraryFile) -DgroupId=$(groupId) -DartifactId=$(artifactId) -Dversion=$(libraryVersion) -Dpackaging=$(soExtension)
這里的 soExtension 可以是dll, so,dylib取決于作業系統。這兩個檔案最終位于 Maven 本地存盤庫的同一位置,即.m2/repository/groupId/artifactId/versionId
但是,我觀察到最初稱為 的本機庫在存盤庫中libmylibrary.so被 Maven 系統地重命名mylibrary.so。結果,即使為 java 提供了正確的庫路徑(-Djava.library.path選項),它也會發出鏈接錯誤,因為它找不到正確的庫名稱(它確實需要“lib”前綴,至少在我可用的實作中)。
鏈接錯誤可以通過以下幾種方式解決:
- 通過將檔案(由 Maven 修剪)重命名為正確的名稱
- 通過之后創建鏈接(在支持鏈接的系統上)。
前兩種解決方案是一種相當笨拙的方法,因為它們假設了解 Maven 存盤庫的內部結構(違背了封裝原則)。
- 另一種解決方案是不依賴 Maven,并將本機庫安裝在通常需要動態庫的系統目錄下(LD_LIBRARY_PATH 或等效項)。這是我最后選擇的解決方案,但我發現它相當脆弱且難以維護,因為兩個檔案(jar 和本機庫)現在都分隔在兩個不同的位置。它也使軟體包的卸載更加困難。
有誰知道為什么 Maven 安裝系統的行為方式是這樣的?如果有解決方法?
謝謝
uj5u.com熱心網友回復:
存盤庫中工件的名稱是由生成的,artifactId并且不可能更改它。如果你喜歡或需要改變那你必須改變artifactId。
為了在特定平臺上運行它,我將創建一種包含正確命名的工件的安裝包。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/488034.html
