JVM系列:(四)打包

原文链接:JVM系列:(四)打包


一 什么是打包

打包是将项目中编写的类、以及依赖第三方的jar包,合并到一个 jar 或 war 包内,并在打包后的项目的配置文件中指定入口类文件路径,以便JVM能够找到入口类并加载运行项目。

二 为什么要打包

一个项目的开发可能会有很多人参与,产生大量的Java源码文件以及配置文件,类之间会相互调用从而配合完成某个功能。

项目中还会依赖第三方包提供的功能jar包,如数据库驱动包、数据库连接池druid、数据库访问层框架mybatis、IOC容器spring、RPC远程调用dubbo、注册中心zookeeper、缓存服务Redis、单元测试框架junit等等。

如果我们将开发完成的项目编译后仍然会有很多文件,这样不仅不利于项目的传播、外部的依赖、更不利于项目的部署(文件个数及体量)。如果我们将这些编译后的文件打包为符合JVM类加载规范的压缩包(jar、war),通过配置文件指定项目的入口文件路径,这样我们部署项目只需要把压缩包上传到服务器指定目录就可以了。如果有外部系统需要依赖我们提供的功能,也只需要把我们打包后的jar包导入项目。

3690542-fe79266ab261de2b.png
打包示意图

三 怎么打包

3.1 打包命令

首先我们看一下打包命令 jar 的使用说明:

用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
选项:
    -c  创建新档案
    -t  列出档案目录
    -x  从档案中提取指定的 (或所有) 文件
    -u  更新现有档案
    -v  在标准输出中生成详细输出
    -f  指定档案文件名
    -m  包含指定清单文件中的清单信息
    -n  创建新档案后执行 Pack200 规范化
    -e  为捆绑到可执行 jar 文件的独立应用程序
        指定应用程序入口点
    -0  仅存储; 不使用任何 ZIP 压缩
    -P  保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
    -M  不创建条目的清单文件
    -i  为指定的 jar 文件生成索引信息
    -C  更改为指定的目录并包含以下文件
如果任何文件为目录, 则对其进行递归处理。
清单文件名, 档案文件名和入口点名称的指定顺序
与 'm', 'f' 和 'e' 标记的指定顺序相同。

示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中: 
       jar cvf classes.jar Foo.class Bar.class 
示例 2: 使用现有的清单文件 'mymanifest' 并
           将 foo/ 目录中的所有文件归档到 'classes.jar' 中: 
       jar cvfm classes.jar mymanifest -C foo/ .

3.2 编写测试代码

  • 工具类 Hello.java
package me.qbian;

public class Hello {
    public static void say(String name) {
        System.out.println("hello " + name);
    }
}
  • 入口类 Main.java
package me.qbian;

public class Main {
    public static void main(String[] args) {
        for (String arg : args) {
            System.out.println("启动参数:" + arg);
        }

        Hello.say("java");
    }
}
  • 打包配置文件 MANIFEST.MF (注意最后有一个换行)
Manifest-Version: 1.0
Created-By: 1.8.0_111 (Oracle Corporation)
Main-Class: me.qbian.Main

以上三个文件在同一文件目录下。最后在当前目录新建文件夹 classes。当前文件夹文件结构如下:

./classes
Hello.java
Main.java
MANIFEST.MF

3.3 打包测试代码

  • 使用 javac 命令编译测试代码到 classes 文件夹
// -d 指定编译后的文件所在路径
// 编译的时候会根据包名自动创建包文件夹
javac *.java -d ./classes

编译后的当前文件夹文件结构如下(注意其中的 me/qbian 文件夹都是编译的时候根据包名自动创建的):

./classes/me/qbian/Hello.class
./classes/me/qbian/Main.class
Hello.java
Main.java
MANIFEST.MF
  • 使用jar命令对已编译的.class文件打包
// 使用当前文件夹下的打包配置文件 MANIFEST.MF
// 对当前 classes 文件夹下所有文件进行递归打包
// 打包后的包名字为 test.jar
jar cvfm test.jar MANIFEST.MF -C classes/ .

打包后的当前文件夹文件结构如下(多出来了一个打包文件 test.jar):

./classes/me/qbian/Hello.class
./classes/me/qbian/Main.class
Hello.java
Main.java
MANIFEST.MF
test.jar

3.4 运行打包文件

  • 不带启动参数,使用 java 命令运行打包文件:
java -jar test.jar

控制台输出运行结果:

hello java
  • 带上启动参数,使用 java 命令运行打包文件:
java -jar test.jar qbian 1 2

控制台输出运行结果:

启动参数:qbian
启动参数:1
启动参数:2
hello java

四 总结

今天我们介绍了什么是打包、为什么要打包以及怎么打包运行项目。打包是软件开发过程中由本地编辑器到线上服务器中必不可少的一环,了解和熟悉打包也是我们的必修课之一。


接下来我们将介绍:

  • 编译后的 .class 文件结构

3690542-7a4fe9565bc0b9b0.jpg
扫码关注有惊喜

猜你喜欢

转载自blog.csdn.net/weixin_34074740/article/details/87050005