在運行jar時自動加載指定的jar包


初學Java的人經常遇到的一個問題是:如果一個程序依賴某個文件夾下的一堆jar包,那么啟動它的時候就需要在java -cp參數后面一個一個的加上jar包的名稱,很不方便。
        比如主程序類叫Main,在目錄lib下有aaa.jar,bbb.jar,ccc.jar,則需要輸入以下命令才能執行:java -cp lib/aaa.jar;lib/bbb.jar;/lib.ccc.jar  Main
        (linux系統下用冒號,windows下用分號)。
        如果jar包少,倒也不是很麻煩,但如果依賴的jar包數量很多的話,一個個的輸就比較麻煩了,當然我們也可以借助一些腳本或者Ant來實現自動化,但總覺得殺雞焉用牛刀,反而把事情弄麻煩了。
我自己是這樣解決的:
java -Djava.ext.dirs=./lib -cp ./bin Main    (假設主程序類Mian.class放在bin目錄下)
       正如你說看到的,-Djava.ext.dirs起到了關鍵作用,它將告訴JVM從那里加載一些類,為了方便理解記憶,順便補充一點ClassLoader的常識:
       Java的類裝載模型是一種代理(delegation)模型。當JVM 要求類裝載器CL(ClassLoader)裝載一個類時,CL首先將這個類裝載請求轉發給他的父裝載器。只有當父裝載器沒有裝載並無法裝載這個類時,CL才獲得裝載這個類的機會。這樣, 所有類裝載器的代理關系構成了一種樹狀的關系。樹的根是類的根裝載器(bootstrap ClassLoader) , 在JVM 中它以"null"表示。除根裝載器以外的類裝載器有且僅有一個父裝載器。在創建一個裝載器時, 如果沒有顯式地給出父裝載器, 那么JVM將默認系統裝載器為其父裝載器。
       根(Bootstrap) 裝載器:該裝載器沒有父裝載器,它是JVM實現的一部分,從sun.boot.class.path裝載運行時庫的核心代碼。 
       
       擴展(Extension) 裝載器:繼承的父裝載器為根裝載器,不像根裝載器可能與運行時的操作系統有關,這個類裝載器是用純Java代碼實現的,它從java.ext.dirs (擴展目錄)中裝載代碼。(這一段就是為什么可以通過設置-Djava.ext.dirs來加載一堆jar的原理)




自動加載所有jar包的Java程序啟動腳本
還記得最初寫Java程序啟動腳本時的無知和齷齪,為了指定CLASSPATH屬性需要將每一個jar包的路徑復制並粘貼到腳本里面,費時頗多。現假定lib目錄在上級目錄,總結Linux,Windows下的Java程序啟動腳本如下:
l  Linux
Startup.sh
for i in ../lib/*;
do CLASSPATH=$i:"$CLASSPATH";
done
 
export CLASSPATH=:$CLASSPATH
 
java -classpath .:${CLASSPATH} ***.***.***.startup
l  Windows
Startup.bat
@echo off
setLocal EnableDelayedExpansion
set CLASSPATH="
for /R ../lib %%a in (*.jar) do (
  set CLASSPATH=!CLASSPATH!;%%a
)
set CLASSPATH=!CLASSPATH!"
 
java ***.***.***.startup
 
pause

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM