maven打包oracle jdbc驅動

wls1036發表於2019-01-19

背景

由於版權問題,maven中央倉庫缺少oracle jdbc的驅動,這個給開發帶來了很多不便利性。也出現各種各樣的解決方案,基本就兩種思路:

  • 將oracle驅動安裝到本地倉庫,這個需要大家統一好名稱和版本
  • 使用第三方倉庫

不管哪種方案,本來maven就是為了方便開發人員管理包依賴,這樣一來反而更麻煩。當然,不是maven的錯,oracle這事做的確實夠sb。(聽說oracle要對java進行收費???)
那麼有沒有更好的方案,假設你現在開發了一個框架,框架支援多資料庫,並且已經將jar包提交至maven中央倉庫,如果你的jar包裡面就已經包含了oracle驅動,那麼使用框架的人就不用額外再去匯入驅動。

這種方案有以下幾個小問題

  • 會不會有版權問題(這個不是很瞭解)
  • 驅動升級怎麼辦
  • 怎麼把驅動打到jar包裡

關於驅動升級問題,可以對jar包釋出多個版本,比如純淨版不包含驅動,驅動xxx版包含不同版本的驅動。

本文主要探討的就是第三個問題,怎麼把驅動打到jar包裡

背景交代完畢,正文開始。

實現

遇到的問題

你可能覺得,這是個很簡單的事,通過idea的Artifacts不就行了。是的,如果你只是想在本地打一個jar包,這種方式簡單方便。但如果要上傳到maven,就得使用maven來打包,maven是不管你ide是怎麼配置的,而且maven不會將依賴包打到jar包裡的。有幾個方案可以考慮

  • 藉助maven外掛maven-assembly-plugin可以實現自定義打包,但是該外掛是將依賴包全部放在lib目錄下,這個不是我的本意,我的本意是將依賴包裡的class檔案解壓到根目錄下,和自開發的jar包同一個目錄下。(這個外掛我研究了很久不能實現就放棄了,如果有知道怎麼實現的讀者歡迎留言)
  • 自己寫外掛實現,其實難度也不大,就是麻煩點
  • 藉助maven指令碼執行外掛exec-maven-plugin執行自定義指令碼對maven打包後的jar包進行”改造”。

最終選擇了第三個方案,寫shell指令碼實現自定義打包

配置

首先引入外掛的依賴
pom.xml

<build>
    <plugins>
        <plugin>
            <artifactId>exec-maven-plugin</artifactId>
            <groupId>org.codehaus.mojo</groupId>
            <executions>
                <execution>
                    <id>asan</id>
                    <phase>package</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>${basedir}/scripts/package.sh</executable>
                        <arguments>
                            <argument>${project.build.directory}</argument>
                            <argument>${project.build.finalName}</argument>
                            <argument>/Users/asan/u01/docker/lib/ojdbc6.jar</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  • phase:在打包這個生命週期結束後執行該指令碼
  • executable:指令碼目錄位置
  • arguments:傳給指令碼的引數,這裡傳了三個引數
  • ${basedir}:當前目錄,就是專案所在目錄
  • ${project.build.directory}:maven構建目錄,就是target目錄
  • ${project.build.finalName}:maven打包名稱
  • /you/path/ojdbc6.jar:要打進去的jar包路徑

指令碼

package.sh

v_workspace=$1/tmp
v_name=$2.jar
v_depency=$3
v_depency_name=`basename $3`
echo "workspace==>$v_workspace"
echo "name==>$v_name"
echo $v_depency
echo $v_depency_name
rm -rf $v_workspace
mkdir -p $v_workspace
cp $v_depency $v_workspace
cd $v_workspace
jar -xf $v_workspace/$v_depency_name
rm -rf $v_workspace/$v_depency_name
rm -rf META-INF/
cp $1/$v_name $v_workspace
for file in `ls $v_workspace`
do
    if [ -d $file ]
    then
        jar -uf $v_workspace/$v_name $file
    fi
done
rm -rf $1/$v_name
mv $v_workspace/$v_name $1/$v_name

整個指令碼的大概流程如下

  1. 建立一個臨時目錄v_workspace
  2. 將依賴包複製到臨時目錄下
  3. 解壓依賴包
  4. 刪除jar包和META-INF資料夾
  5. 將專案的jar包複製到臨時目錄下
  6. 遍歷所有資料夾,將資料夾通過命令jar -uf更新到專案jar包裡
  7. 用新的jar包替換掉老的jar包

寫在最後

現在指令碼里只支援一個jar包,稍微修改下就可以支援多個,或者你可以在自己本地把多個jar包用jar -uf打到一個jar包裡,再執行指令碼。

相關文章