什么是jar包
jar是Java Archive文件的后缀,它代表的含义是将java的字节码文件以及相关的静态资源进行归档。我们知道通常一个java程序需要包含多个字节码文件,为了方便在网络上进行传输就需要进行压缩,而jar包实际上就是zip压缩文件。
如何打jar包
这块网络上有些资料没有讲明白,照着操作可能浪费不少时间然后报奇奇怪怪的错误。
首先我们准备一个文件夹叫SayHello, 其中包括了resources文件夹(存放静态资源的地方),当然你也可以不创建文件夹,直接打包一个字节码文件不包含静态资源也是可以的。
我们现在想要打包一个类叫SayHello
package classes;
public class SayHello{
public static void PrintHello(){
System.out.println("Hello, jar");
}
public static void main(String[] args) {
System.out.println("ok");
}
}
- 首先需要将java源文件编译成字节码文件到指定目录下
javac SayHello.java -d ./SayHello/
- 编写Manifest文件
这个文件你可以任意起名,我这里按照习惯就叫做manifest,该文件用作jar包的清单文件,作说明之用
Manifest-Version: 1.0
Main-Class: classes.SayHello
第一个表示清单的版本,默认都是1.0,Main-Class表示程序的入口类,如果不写,那么该jar包就不可执行,当工具包来用
注意:后面要有一个空格,最后一个字段后需要有一行回车。
- 用jar命令打包
jar -cvfm SayHello.jar manifest.txt -C SayHello .
-c表示创建jar包,v是在控制台打印相关信息,-f用于指定jar包名称 -m是指定jar包的清单。 -C指定包含的文件 . 表示包含该文件下的所有文件。
- 执行jar包
java -jar SayHello.jar
打包jar的核心想法就是你得指定你要打包的文件或者文件夹,这是-C参数指定的。其次,你需要在清单文件中告知文件执行的入口类,否则,你如果写了很多包含main方法的类,程序怎么知道该从哪儿执行。
引用我们自己写的jar包
在本地可以通过CLASSPATH的方式,添加我们自己写的类的路径,从而使用自己写的类。我们现在有了自己的jar包,上面的SayHello类有一个PrintHello的静态方法,如果我想新创建一个jar包,并将SayHello.jar作为依赖,使用它的PrintHello方法该怎么操作呢?
- 编写TestHello类
import classes.SayHello;
public class TestHello{
public static void main(String[] args) {
SayHello.PrintHello();
}
}
这个类的功能很简单,就是使用SayHello的PrintHello方法,但如果我们直接去编译这个java文件肯定会报错,它找不到SayHello类,原因是我们没有把SayHello.jar添加到CLASSPATH中,为了编译通过,可以使用javac的-cp参数
- 编译TestHello
javac -cp SayHello.jar TestHello.java
此时可以通过编译,但无法执行TestHello字节码文件,原因是,编译出来的TestHello并没有包含SayHello中的内容,且CLASSPATH中没有相关类的信息。
- 将TestHello打成jar包
jar -cvfm TestHello.jar manifest.txt TestHello.class lib
- manifest的内容
Manife-Vesion: 1.0
Main-Class: TestHello
Class-Path: ./lib/SayHello.jar
多了个Class-Path配置项,表明从当前jar包的什么位置找需要的类。
我们将SayHello.jar放在了新建的lib目录下,并且在给TestHello打包时,指定了TestHello.class和lib这两个需要包含的文件和文件夹。如果需要包含多个jar包则用英文空格分开