在运行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
原文地址:https://www.cnblogs.com/blogsme/p/3177806.html