目录

Java jar包指令笔记

Java中Jar包运行之-jar和-cp命令

或多或少,我们都会见到用这两种命令启动java程序,最基本的用法如:

java [options] -jar xxx.jar [args]

java [options] -cp xxx.jar classname [args]

那这两种用法有什么区别呢?

我们先写一个简单的测试类(为了方便说明问题,不借助开发工具):

1)在本机随便找个目录,创建com.test目录,并编写HelloTest.java文件:

./1.png

1
2
3
4
5
6
7
8
9
package com.test;
 
public class HelloTest {
 
	public static void main(String[] args) {
		String name = args[0];
		System.out.println("hello:"+name);
	}
}

2)编译:

./2.png

3)打jar包:

./3.png

4)我们尝试用最开始说的两种命令来执行

./4.png

发现-jar命令执行的结果提示:没有主清单属性,什么意思呢?

首先说下jar包,jar包跟我们通常认知的.zip压缩文件,是一样一样的,我们甚至完全可以用普通zip压缩工具来压缩com目录,然后用java -cp com.zip com.test.HelloTest everybody照样能运行,不同的是,用jar命令打出的jar包会多出来一个东西:

./5.png

看到没,一个META-INF目录,里面有一个文件:MANIFEST.MF,其内容如下:

1
2
Manifest-Version: 1.0
Created-By: 1.8.0_171 (Oracle Corporation)

这个文件就是jar的清单文件,可以理解成一个标识配置文件,上面说的java -jar执行结果提示:没有主清单属性,就是因为我们的清单文件中少了一样属性,这个属性是:Main-Class,它声明了jar包的默认入口类,也是java -jar运行时开始执行的类,其格式为:

Main-Class: com.test.HelloTest

我们把test.jar解压后,在MANIFEST.MF文件中加入该属性:

./6.png

然后用.zip格式直接再次压缩后(命名为test2.jar),执行java -jar test2.jar

./7.png

注意:清单属性配置格式问题,冒号后面需要一个空格,否则会报Error: Invalid or corrupt jarfile错误,属性结束必须换行,否则仍然找不到属性

当然,实际上也不需要如此麻烦,我们在打jar包时可以通过-e参数指定默认入口,会自动生成Main-Class属性,此时jar包就是一个可执行jar文件:

./8.png

用java -jar运行jar包时,虚拟机忽略系统中的classpath配置,如果有依赖jar,需要在清单属性中指定,格式为:

1
Class-Path: servlet.jar infobus.jar acme/beans.jar

多个jar包之间用空格隔开,其位置是相对于当前运行的jar包所在的目录;

用java -cp运行时,其cp本身就是classpath的意思,对于多个依赖的jar格式为:

1
java -cp test.jar;test1.jar;test2.jar com.test.HelloTest

注意:jar包之间的分隔符在windows上是分号";",而在linux中是冒号":"。

综上所述:

java -jar用来执行可执行jar包,其可执行的特性,由jar包中的清单属性Main-Class决定;

java -cp命令是纯粹的java命令,在指定的classpath中查找java类文件并执行,使用更灵活;