java命令行启动程序时,一般需要指定classpath,如下:
java -cp "./:./lib/a.jar:./lib/b.jar" com.a.b.c.StartMain
依赖的jar包都在lib目录下。
如果lib目录下的jar过多,一般会使用shell的帮助
CLASS_PATH=./
for jar in ./lib/*.jar; do
CLASS_PATH=$CLASS_PATH:$jar
done
java -cp $CLASS_PATH com.a.b.c.StartMain
这里必须的把每个jar包列出来,jar包里包含许多class文件,一个jar相当于一个目录。另外,网上看到也可以通过
java -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:./:./lib com.a.b.c.StartMain
方式启动(注意必须加上$JAVA_HOME/jre/lib/ext
,否则一些重要的JDK类将找不到)。
两者都可以达到启动程序的目的,但是机制不同,指定classpath时,加载com.a.b.c.StartMain 类使用的是sun.misc.Launcher$AppClassLoader
加载器,
而使用-Djava.ext.dirs方式时是 sun.misc.Launcher$ExtClassLoader
加载器。
有三个系统类加载器,并且加载类的顺序依次为
- Bootstrap CLassloder
加载 $JAVA_HOME/jre/lib下的jar、class - Extention ClassLoader(ExtClassLoader)
加载$JAVA_HOME/jre/lib/ext 目录下的jar、class - AppClassLoader(AppClassLoader)
加载-classpath指定的jar、class
上述的第二种启动应用程序的方式,直接使用了ExtClassLoader 系统加载器。而原则上java的程序期望使用AppClassLoader加载器。