java如何启动应用程序、 -cp和-jar的区别、类加载过程
java如何启动应用程序、 -cp和-jar的区别、类加载过程
文章目录
- java如何启动应用程序、 -cp和-jar的区别、类加载过程
- 问题1:如何通过java启动应用程序
- 1、java classname
- 2、java -jar jarName
- 如何退出
- 方式一 java [ options ] classname [ args ]
- 方式二 java [ options ] -jar filename [ args ]
- 问题2:java -cp 、-classpath为什么在 -jar 启动jar包无效
- 问题3: -Xbootclasspath 、-Djava.ext.dirs、-cp区别、类加载过程
- bootstrap loader
- extension class loader
- user class loader
问题1:如何通过java启动应用程序
两种方式:
1、java classname
java [ options ] classname [ args ]
2、java -jar jarName
java [ options ] -jar filename [ args ]
options 命令行选项由空格分隔。请参阅选项。
classname 要启动的类的名称。
filename 要调用的Java归档(JAR)文件的名称。仅与该-jar选项一起使用。
ARGS 传递给main()由空格分隔的方法的参数。类文件名或JAR文件名后面的参数传递给main()方法。
默认情况下,不是该java命令选项的第一个参数是要调用的类的完全限定名称。如果-jar指定了该选项,则其参数是包含应用程序的类和资源文件的JAR文件的名称。启动类必须Main-Class在其源代码中的清单标题中指明。
JRE在三组位置中搜索启动类(以及应用程序使用的其他类):
1、引导类路径(bootstrap classpath),
2、已安装的扩展(extent classpath)
3、用户的类路径(user application classpath)。
上图java启动类加载过程:
这里类的加载涉及到双亲委派机制。
如何退出
当启动器被错误的参数,严重错误或由JVM抛出的异常调用时,通常会由启动器返回以下退出值。但是,Java应用程序可能会选择使用API调用返回任何值System.exit(exitValue)。这些值是:0:成功完成 >0:发生错误
方式一 java [ options ] classname [ args ]
java -cp 和 -classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar包之类,需要全路径到jar包,window上分号“;”分割,unix上“:”号分割。
格式:
java -cp .;myClass.jar packname.mainclassname
表达式支持通配符
扫描某路径下所有jar包,例如:
java -cp .;c:\classes01\myClass.jar;c:\classes02*.jar packname.mainclassname
通配符说明:
包含星号(*)的类路径条目与类文件不匹配。要在单个目录中匹配类和JAR文件mydir,请使用mydir:mydir/或mydir/:mydir。选择的顺序决定了mydirJAR文件之前加载的类和资源是否被加载,mydir反之亦然。
子目录不会被递归搜索。例如,mydir/*搜索JAR文件只有在mydir,不mydir/subdir1,mydir/subdir2等。
##注意:
- -cp 和 -classpath 使用效果一样
- -多个启动程序可以引用相同jar进行启动程序
- Java解释器将按照它们出现在类路径变量中的顺序查找目录中的类
方式二 java [ options ] -jar filename [ args ]
启动含manifest的jar包,可以使用
java -jar <jar-file-name>.jar
如果jar里没有 manifest,则可以使用
java -cp foo.jar full.package.name.ClassName
当main类依赖多个jar时,可以把多个jar打包到一个目录,
然后用-Djava.ext.dirs指定该目录,引用依赖的多个jar。如:
java -Djava.ext.dirs=<多个jar包的目录> com.test.HelloWordMain
也可以用-Xbootclasspath引导类路径方式引用 jar包依赖。使用方式如下:
-Xbootclasspath: 完全取代基本核心的Java class 搜索路径. 不常用,否则要重新写所有Java 核心class
-Xbootclasspath/a: 后缀在核心class搜索路径后面.常用
-Xbootclasspath/p: 前缀在核心class搜索路径前面.不常用,避免
问题2:java -cp 、-classpath为什么在 -jar 启动jar包无效
注意:当您使用该-jar选项时,指定的JAR文件是所有用户类的来源(mainfest文件配置),而其他类路径设置将被忽略。
什么意思呢?
就是-jar 启动jar包方式。-classpath 、-cp参数将被忽略不生效,类似spring boot的jar启动应用就不能通过此方式设置类路径。
问题3: -Xbootclasspath 、-Djava.ext.dirs、-cp区别、类加载过程
bootstrap loader
-Xbootclasspath 设置的是引导类
语法如下:
(引用多个jar包请用分隔符,与classpath参数类似,unix使用:号,windows使用;号,这里以unix为例)
java -Xbootclasspath/a:/usrhome/thirdlib.jar: -jar yourJarExe.jar
扩展类加载过程:
- 加载平台类(如java.lang.Object,java.lang.Thread等)
- 从rt.jar加载类($ JRE_HOME / lib / rt.jar)
- -Xbootclasspath可用于更改引导类路径-Xbootclasspath / p:和-Xbootclasspath / a:可用于预先添加/追加其他引导目录 - 这样做时非常谨慎。在大多数情况下,您希望避免使用引导类路径进行播放。
- 在Sun的实现中,只读System属性sun.boot.class.path 被设置为指向引导类路径。请注意,在运行时不能更改此属性 - 如果更改了无效的值。
- 该加载器由Java null表示。即,例如,java.lang.Object.class。getClassLoader()会返回null(所以对于其他引导类如java.lang.Integer,java.awt.Frame,java.sql.DriverManager等)
extension class loader
在java命令中通过-Djava.ext.dirs指定扩展类目录
扩展类加载过程:
- 从已安装的可选包中加载类
- 从$ JRE_HOME / lib / ext目录下的jar文件加载类
- 系统属性java.ext.dirs可能被设置通过使用-Djava.ext.dirs命令行选项更改扩展目录。
- 在Sun的实现中,这是sun.misc.Launcher $ ExtClassLoader的一个实例(实际上它是sun.misc.Launcher类的内部类)。
- 以编程方式,您可以读取(只读!)系统属性java.ext.dirs以查找哪些目录用作扩展目录。请注意,您无法在运行时更改此属性 - 如果更改了无效的值。
使用方式:
Java exten class 存放在{Java_home}\jre\lib\ext目录下.当调用Java时,对扩展class路径的搜索是自动的.总会搜索的.这样,解决的方案就很简单了,将所有要使用的第三方的jar包都复制到ext 目录下.
user class loader
java命令设置方式:-cp -classpath设置
用户应用类加载过程:
- 从应用程序类路径加载类
- 使用应用程序类路径:环境变量CLASSPATH(或)、带有Java启动器的-cp或-classpath选项读取类路径
- 如果CLASSPATH和-cp都丢失,则“。” (当前目录)被使用。只读System属性java.class.path具有应用程序类路径的值。请注意,您无法在运行时更改此属性 。
- java.lang.ClassLoader.getSystemClassLoader()返回这个加载器
- 这个加载器也被(称为“系统类加载器”)(不会与加载Java“系统”类的引导加载器混淆)。
- 这是加载Java应用程序的“main”类(使用主要方法的类)的加载器。在Sun的实现中,这是sun.misc.Launcher $AppClassLoader的一个实例(实际上它是sun.misc.Launcher类的内部类)。
- 默认的应用程序加载器使用扩展加载器作为其父装载器。
- 您可以通过命令行选项-Djava.system.class.loader更改应用程序类加载器。该值指定java.lang.ClassLoader类的子类的名称。首先默认的应用程序加载器加载命名的类(并且这个类必须在CLASSPATH或-cp中)并创建它的一个实例。新创建的加载器用于加载应用程序主类。
java官方文档参考:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/classpath.html#CBHHCGFB
https://blogs.oracle.com/sundararajan/understanding-java-class-loading
还没有评论,来说两句吧...