Java命令行下Jar包打包小结
作者:Allocator 发布时间:2023-01-04 19:25:44
jar包打包实现
jar包打包可以使用jar指令实现打包,在命令行中输入jar可以查看jar指令的内容
从最后显示的两个示例看出存在两种打包的方法,两者的区别就是是否使用自己定义的MANIFEST清单文件。第一个示例没有使用MANIFEST文件进行打包,所以最终生成的jar包中MANIFEST文件为默认文件,这种方式适用于比较简单的jar包结构,不存在其他jar包依赖以及生成的jar包不需要可执行。这种方式生成的jar包不能使用java -jar XXX.jar
命令执行,因为MANIFEST文件中未指定程序入口。而第二个实例是比较常用的打包方式,即是使用自定义的MANIFEST文件参与打包,这样能够实现往包中添加依赖,并且可以指定程序入口,实现java -jar XXX.jar
直接运行jar包。
第一种简单的打包方式
最简单的就是在当前文件夹下将编译的class字节码文件进行打包输出。示例如下:
编写三个java文件,test1.java test2.java 以及Main.java
public class test1
{
public static void main(String[] args)
{
}
public void display()
{
System.out.println("this is class test1");
}
}
以及test2.java 文件
public class test2
{
public static void main(String[] args)
{
}
public void display()
{
System.out.println("this is class test2");
}
}
Main.java
public class Main
{
public static void main(String[] args)
{
for(String a:args)
{
System.out.println("给定的参数"+a);
}
test1 t1 = new test1();
t1.display();
test2 t2 = new test2();
t2.display();
}
}
命令行下将这三个文件进行编译,使用javac命令实现编译。
用jar指令将编译的class文件打包
打包过程中有显示已添加清单。用解压工具打开生成的test.jar
包,可以看到如下的结构:
除了编译的三个class文件外多了一个META-INF文件夹,里面有一个MANIFEST.MF(清单文件)的文件,这个文件的作用非常重要,后面说明。我们先看它里面的内容
非常简单的清单,只包含清单版本与java版本。
这个时候执行java -jar test.jar
有如下效果:
没有主清单属性报错。这是因为我们使用第一种方法生成jar使用了默认的清单,默认清单没有指定程序入口,所以出错。
可以直接更改jar包中的MANIFEST文件(解压工具打开,更改后保存),改成如下效果:
再一次执行java -jar test.jar
后程序输入正确内容:
在MANIFEST文件中添加了Main-Class属性指定了程序入口,实现了直接执行jar文件。
所以说使用默认的MANIFEST是不能直接执行jar文件,要么使用自己定义的MANIFEST文件打包,要么更改包中的MANIFEST文件。
第二种打包方式
第二种打包方式更加通用,一般情况下java文件第一行都是package XXX;
即是包名,也决定了编译后的class文件存在的路径。当有多个java文件要编译打包并且他们存在不同的包名时,如果还是按照第一种方法打包时一个文件一个文件的写非常不现实,所以有了第二种方法。将所有要打包的class文件存在的目录以及依赖的jar包全部放在一个根文件夹里面(比如是foo),然后编写MANIFEST清单文件,指定程序入口以及其他添加的依赖的jar包。在执行指令:
注意 上面的指令中foo/
文件夹后面有一个空格还有一个点
下面看一个例子
同样还是test1.java与test2.java以及Main.java 但是各自有自己的包名。
package cn.mytest1;
public class test1
{
public static void main(String[] args)
{
}
public void display()
{
System.out.println("this is class test1");
}
}
package cn.mytest2;
public class test2
{
public static void main(String[] args)
{
}
public void display()
{
System.out.println("this is class test2");
}
}
package cn.mymain;
import cn.mytest1.test1;
import cn.mytest2.test2;
public class Main
{
public static void main(String[] args)
{
for(String item:args)
{
System.out.println("传递参数"+item);
}
test1 t1 = new test1();
test2 t2 = new test2();
t1.display();
t2.display();
}
}
同样使用javac 指令编译,三个class文件存在于不同的路径下,因为他们包名不一样。把编译号的含有class文件的文件夹全部放在foo文件夹下:
然后在foo 外面写一个MANIFEST文件:
MANIFEST内容如下:
注意:MANIFEST 文件最后一行是空行。
命令行下执行指令:jar cvfm test.jar MANIFEST.MF -C foo/ .
在命令行下测试jar包是否能够直接运行了,使用指令java -jar test.jar
正确打包,成功运行jar.
MANIFEST文件介绍
通过上面的两个例子,可以看到MANIFEST文件对于jar打包都是必须的。MANIFEST文件描述了打包后的jar文件的详细信息,存在于打包后的META-INF 的文件夹.一个简单的MANIFEST文件主要内容如下:
主要就是Manifest-Version Main-Class Class-Path这三个属性在制作jar包时非常重要.Manifest-Version 是版本号,照着写就行。Main-Class则是jar包的入口程序,指定运行的类的全称(一定要包含包名),这样可以使用java -jar name.jar
直接运行jar包。第三个Class-Path是指的打包时需要依赖的其他jar包,打包的时候自己的程序中也可能含有其他的jar包所以要添加依赖。
注意每个MANIFEST属性冒号与内容之间都有一个空格,并且写完后最后还要留有一行空行,不然运行时还是出现找不到主清单属性的错误
小结
jar文件打包容易出错的地方就是Manifest清单文件的编写,容易出一些格式上的错误比如属性的冒号和内容之间少空格,Class-Path中添加依赖之间没有空格,依赖文件过多,多行书写的时候每行开头没加空格,文件最后一行没有空行等等。写MANIFEST文件的时候注意这些关键的地方就不会在打包上面耗费太多的时间。
来源:http://blog.csdn.net/allocator/article/details/51704846
猜你喜欢
- 在开发过程中,我们经常需要将数据库查询到的值放入jsp页面进行显示,在springmvc的controller中,我们采用request将数
- 1.前言string是属于引用类型的,这个大家都知道吧?但是平常在使用的过程中,发现它还是拥有一些值类型的特征的,这到底是为什么呢?原因就是
- 前言本文主要介绍其具体的实现思路(视频仅有代码输入,并无过程介绍等),同时,在原本实现的基础上,进行了多处修改和优化,具体参见下面的内容。优
- 1、输出矩形以此矩形案例(4行,9列的矩形)为例public static void main(String[] args) {  
- 一. 封装封装是面向对象的三大特性之一;面向对象程序三大特性:封装、继承、多态 。封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和
- java 使用异常的好处总结一、分析Java异常处理机制确实比较慢,这个“比较慢”是相对于诸如String、Integer等对象来说,单单从
- 一、数据类型与变量的介绍在程序运行的过程中计算机需要记录大量的状态 数据(这里我们统称数据)。那这些数据都存放在哪呢?程序在运行过程中的数据
- 一、安装MongoDB4.0.3(××)1.1、官方安装文档https://docs.mongodb.com/manual/tutorial
- 简介过滤器是AOP(面向切面编程)思想的具体实现。可以过滤浏览器发出的请求,并且决定放行请求还是中断请求。在浏览器对服务器发起请求或者服务器
- 一、业务需求实现省份与城市的二级联动二、实现效果三、代码实现1. province_city.jsp前端界面实现<%@ p
- 本文实例讲述了JavaMail实现邮件发送的方法。分享给大家供大家参考。具体如下:下载 activation.jar 和 mail.jar配
- 前言LocalDateTime、LocalDate、LocalTime 是 Java8 全新的日期框架,加强了对时间的管理,有很多特别好用的
- 刚开始我以为熔断和降级是一体的,以为他们必须配合使用; 只不过名字不一样而已,但是当我经过思考过后,发现他们其实不是一个东西;降级什么是服务
- 什么是文件上传?文件上传就是把用户的信息保存起来。为什么需要文件上传?在用户注册的时候,可能需要用户提交照片。那么这张照片就应该要进行保存。
- 很多同学对于overload和override傻傻分不清楚,建议不要死记硬背概念性的知识,要理解着去记忆。  
- 最近在做项目的过程中 需要用JWT做登录和鉴权 查了很多资料 都不甚详细有的是需要在application.yml里进行jwt的配置 但我在
- mybatis-plus的代码生成器会在实体类中生成数据库所有字段,我们去用mapper接口查询时,会返回数据库所有的字段。但有些字段不是我
- 单元测试是程序员对代码的自测,一般公司都会严格要求单元测试,这是对自己代码的负责,也是对代码的敬畏。一般单元测试都是测试Service层,下
- 本文实例讲述了java基于swing实现的五子棋游戏代码。分享给大家供大家参考。主要功能代码如下:import java.awt.*;imp
- 查询文档 & 基本操作为了方便学习, 本节中所有示例沿用上节的索引按照ID单个GET class_1/_doc/1查询结果:{ &n