赞
踩
转载并且补充:java -jar/-cp启动添加外部的依赖包
启动java主要有两种方式,分别为:java -jar test.jar、java -cp/-classpath test.jar com.main.Test
。然后分别讲一下这两种方式启动程序时,如何加载外部依赖的包。为了方便大家理解,首先说一下Java的ClassLoader。
ClassLoader
的具体作用就是将class文件
加载到jvm虚拟机
中去。我们都知道在Java中程序是运行在虚拟机中,我们平常用文本编辑器或者是IDE编写的程序都是.java格式的文件,这是最基础的源码,但这类文件是不能直接运行的。需要将.java的文件编译成字节码.class文件,才能加载到JVM中运行,这个过程由ClassLoader来完成,Java自带的ClassLoader有3大类,分别为:
Bootstrap ClassLoader
最顶层的加载类,主要加载核心类库,%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等
。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录
。比如java -Xbootclasspath/a:path
被指定的文件追加到默认的bootstrap路径中。我们可以打开我的电脑,在上面的目录下查看,看看这些jar包是不是存在于这个目录。
Extention ClassLoader 扩展的类加载器
,加载目录%JRE_HOME%\lib\ext
目录下的jar包和class文件。还可以加载-D java.ext.dirs
选项指定的目录。
Appclass Loader
也称为SystemAppClass 加载当前应用的classpath的所有类。
所以,我们要改变这加入外部依赖的jar包,可以分别考虑改变这3个ClassLoader来实现,分别来讲一下这3种实现方法。
Bootstrap ClassLoader 通过改变Xbootclasspath
参数来实现,一般有3种方法:
-Xbootclasspath:
完全取代基本核心的Java class 搜索路径.不常用,否则要重新写所有Java 核心class
-Xbootclasspath/a
: 后缀在核心class搜索路径后面(推荐使用)
-Xbootclasspath/p
: 前缀在核心class搜索路径前面.不常用,避免引起不必要的冲突.
使用Bootstrap ClassLoader的一般方式为:
java -Xbootclasspath/a:test1.jar -jar test2.jar //-jar方式
java -Xbootclasspath/a:test1.jar -cp test2.jar com.test2.Test2 //-cp方式
Extention ClassLoader通过改变参数java.ext.dirs来实现
。java中系统属性java.ext.dirs
指定的目录由ExtClassLoader
加载器加载,如果您的程序没有指定该系统属性(-Djava.ext.dirs=lib)
那么该加载器默认加载
$JAVA_HOME/lib/ext
目录下的所有jar文件。但如果你手动指定系统属性且忘了把$JAVA_HOME/lib/ext路径给加上,那么ExtClassLoader不会去加载$JAVA_HOME/lib/ext下面的jar文件,这意味着你将失去一些功能
,例如java自带的加解密算法实现。所以我们要既要带有原来的lib/ext下的包,也要加入其他依赖,则可以这样写
java -Djava.ext.dirs=%JAVA_HOME%\jre\lib\ext;lib -jar test2.jar
java -Djava.ext.dirs=%JAVA_HOME%\jre\lib\ext;lib -cp test2.jar com.test2.Test2
#java.ext.dirs需要写成目录格式
Appclass Loader加载的是classpath配置的jar包
,java -cp和java -jar命令启动程序的时候,有一些不同,主要为:
java -jar
启动的时候,java VM会屏蔽所有的外部classpath,也就是配置的 -cp/-classpath环境变量会失效,而只以本身jar的内部class作为类的寻找范围。这时候只能通过改变META-INF/MANIFEST.MF
来设置classpath所以这两种方式加载外部类的方法分别为:
java -cp test2.jar;test1.jar com.test2.Test2 #Test是main方法,通过-cp方式加载2个jar包
修改主类jar包 META-INF/MANIFEST.MF
内容种的
Main-Class属性,例如
Main-Class: /home/test1.jar /home/test3.jar
#多个jar包用空格隔开
我的做法是:直接修改java.ext.dirs来加载jar包的属性来实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。