-jar参数运行应用时,设置classpath的方法
转自https://blog.csdn.net/sayyy/article/details/81120749
前言
- 期望在java -jar命令执行java程序时,能够指定classpath
分析
因为使用“-jar”选项(形如:java -jar xxx.jar )来运行一个可执行的jar包时,jar包会覆“-cp”的值。
换句话说,-jar 后面所跟的jar包的优先级别最高。如果指定了-jar选项,所有环境变量和命令行制定的搜索路径都将被忽略。JVM APPClassloader将只会以jar包为搜索范围.
解决方案
Java 命令行提供了如何扩展bootStrap 级别class的简单方法.
- -Xbootclasspath: 完全取代基本核心的Java class 搜索路径.不常用,否则要重新写所有Java 核心class
- -Xbootclasspath/a: 后缀。将classpath添加在核心class搜索路径后面。常用!!
- -Xbootclasspath/p: 前缀。将classpath添加在核心class搜索路径前面.不常用,避免引起不必要的冲突.
示例如下: (分隔符与classpath参数类似,unix使用:号,windows使用;号,这里以unix为例)
//特定的jar到classpath
java -Xbootclasspath/a:/usrhome/thirdlib1.jar:/usrhome/thirdlib2.jar -jar yourJarExe.jar
//添加目录到classpath
java -Xbootclasspath/a:/usrhome/thirdlib1/:/usrhome/thirdlib1/ -jar yourJarExe.jar
//添加当前目录(可执行的jar所在的目录)到classpath
java -Xbootclasspath/a:./ -jar yourJarExe.jar
扩展知识(转)
自JDK 1.2以后,JVM采用了委托(delegate)模式来载入class.采用这种设计的原因可以参考http://java.sun.com/docs/books/tutorial/ext/basics/load.html
归纳来讲:是基于JVM sandbox(沙盒)安装模型上提供应用层的可定制的安全机制.
Java虚拟机(JVM)寻找Class的顺序
1. Bootstrap classes
属于Java 平台核心的class,比如java.lang.String等.及rt.jar等重要的核心级别的class.这是由JVM Bootstrap class loader来载入的.一般是放置在{java_home}\jre\lib目录下
2. Extension classes
基于Java扩展机制,用来扩展Java核心功能模块.比如Java串口通讯模块comm.jar.一般放置在{Java_home}\jre\lib\ext目录下
3. User classes
开发人员或其他第三方开发的Java程序包.通过命令行的-classpath或-cp,或者通过设置CLASSPATH环境变量来引用.JVM通过放置在{java_home}\lib\tools.jar来寻找和调用用户级的class.常用的javac也是通过调用tools.jar来寻找用户指定的路径来编译Java源程序.这样就引出了User class路径搜索的顺序或优先级别的问题.
- 3.1 缺省值:调用Java或javawa的当前路径(.),是开发的class所存在的当前目录
- 3.2 CLASSPATH环境变量设置的路径.如果设置了CLASSPATH,则CLASSPATH的值会覆盖缺省值
- 3.3 执行Java的命令行-classpath或-cp的值,如果制定了这两个命令行参数之一,它的值会覆盖环境变量CLASSPATH的值
- 3.4 -jar 选项:如果通过java -jar 来运行一个可执行的jar包,这当前jar包会覆盖上面所有的值.换句话说,-jar 后面所跟的jar包的优先级别最高,如果指定了-jar选项,所有环境变量和命令行制定的搜索路径都将被忽略.JVM APPClassloader将只会以jar包为搜索范围.
有关可执行jar有许多相关的安全方面的描述,可以参考http://java.sun.com/docs/books/tutorial/jar/ 来全面了解.
这也是为什么应用程序打包成可执行的jar包后,不管你怎么设置classpath都不能引用到第三方jar包的东西了.