jar包本质上是将所有class文件、资源文件压缩打成一个包(也可以选择不压缩),可选择在jar包中生成META-INF/MANIFEST.MF文件,MANIFEST.MF是清单文件,里面可以记录主类、classpath等信息,供虚拟机使用。

接下来的一段时间里,我们将以以下路径学习jar命令和清单文件的相关知识

jar打包class文件

带包class文件jar打包

清单文件的使用

在这篇文章里我们将使用简单的java程序来熟悉jar命令的使用,因为是出于熟练使用jar的目的,下面的操作中可能会啰里啰嗦、重复使用jar命令,以下是本片文章的目录,精简版直接看 jar命令的选项

一 jar命令的选项

用法

选项

本节中使用到的命令

二 只有一个class文件的可执行jar的实现

方法一将Mainjar全部解压修改MANIFESTMF文件后再重新打包

方法二生成jar包的时候为其指定清单文件

方法三为jar包指定清单文件

方法四为jar更新文件文件是清单文件

三 多个class的打包

一. jar命令的选项

用法:

大括号中的选项是必选的,中括号里选项是可选的,jar-file是jar文件;manifest-file是清单文件,即jar包中的META-INF/MANIFEST.MF文件

jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...

1

选项:

-c  (create)创建新档案

-t  列出档案目录

-x  从档案中提取指定的 (或所有) 文件

-u  (update)更新现有档案

-v  在标准输出中生成详细输出

-f  指定档案文件名

-m  包含指定清单文件中的清单信息

-n  创建新档案后执行 Pack200 规范化

-e  为捆绑到可执行 jar 文件的独立应用程序

指定应用程序入口点

-0  仅存储; 不使用任何 ZIP 压缩

-P  保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件

-M  不创建条目的清单文件

-i  为指定的 jar 文件生成索引信息

-C  更改为指定的目录并包含以下文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

本节中使用到的命令

jar uf xx.jar [file … | path]是需要注意的,它在更新完jar文件后会生成新的清单文件,这一点在本篇文章的 “方法4:为jar更新文件,文件是清单文件” 中有实例说明

jar cf xx.jar [file ... | path]  将file等文件或path目录打包成xx.jar

jar cvf xx.jar [file ... | path]  同上,显示详细信息

jar cmf manifest-file xx.jar [file ... | path]  将file等文件或path目录打包到xx.jar,并制定它的清单文件

jar cMf xx.jar [file ... | path]  将file等文件或path目录打包到xx.jar,包中不生成清单文件

jar uf xx.jar [file ... | path]  将file等文件或目录更新到xx.jar,务必注意!!!这个更新会重新生成清单文件

jar uMf xx.jar [file ... | path]  同上,但不会生成清单文件

jar umf manifest-file xx.jar {file ... | path}  将file等文件或path目录更新到xx.jar

jar tf xx.jar  列出xx.jar中所有文件

jar xf xx.jar  把xx.jar中所有文件提取到当前目录

jar xf xx.jar {file ...}  把xx.jar中file等文件提取到当前目录

1

2

3

4

5

6

7

8

9

10

二. 只有一个class文件的可执行jar的实现

首先创建一个jarDemo文件夹,里面放置我们的测试类

mkdir jarDemo

cd jarDemo

touch Main.java

1

2

3

在Main.java里面添加我们的hello world代码,并javac编译

public class Main{

public static void main(String ... args){

System.out.println("hello world");

}

}

1

2

3

4

5

javac Main.java

1

然后将生成的Main.class打包,c选项是创建一个新的jar包,f是指定jar包的名字

jar cf Main.jar Main.class

1

如果附加使用v选项,则会列出详细的打包信息

jar cvf Main.jar Main.class

1

我们可以通过t选项来查看生成的jar中的文件,输出的内容也就是包目录和包文件,可以看到是默认生成MANIFEST.MF文件的

jar tf Main.jar

输出:

META-INF/

META-INF/MANIFEST.MF

Main.class

1

2

3

4

5

6

当然我们也可以通过M选项不生成MANIFEST.MF文件,可以看到包中只有Main.class一个文件

rm Main.jar

jar cMf Main.jar Main.class

jar tf Main.jar

输出:

Main.class

1

2

3

4

5

6

虽然我们已经将Main.class打包了,并且Main.class有main(String … args)入口方法,可是这个jar还是不能执行,因为虚拟机并不知道这个包中的哪个class中是有main方法的

java -jar Main.jar

输出:

Main.jar中没有主清单属性

1

2

3

4

下面还是恢复到有MANIFEST.MF文件的Main.jar包,我们要将他解压,在MANIFEST.MF中添加主类属性

解压jar包的方法有很多种,我们解压的目的是为了查看默认生成的MANIFEST.MF文件,并做修改,最后生成一个可执行的jar包,因为我们的目的是出于熟练使用jar命名,下面我们将使用多个方法实现这个目标

方法一:将Main.jar全部解压,修改MANIFEST.MF文件后再重新打包

因为jar解压命令只能解压到当前目录,这样会造成文件混乱,我们新建一个uncompress文件夹,将Main.jar拷贝到这个文件夹后再解压,可以看到,jar包中所有文件,x选项是提出全部或指定文件,这个例子里是提出全部文件,实际中可以用f选项提出指定文件,比如 >> jar xf Main.jar META-INF/MANIFEST.MF

mkdir uncompress

cp Main.jar uncompress

cd uncompress

jar xf Main.jar

ls -RF

输出:

META-INF/   Main.class  Main.jar

./META-INF:

MANIFEST.MF

1

2

3

4

5

6

7

8

9

10

11

打开META-INF/MANIFEST.MF文件,看到默认生成的清单文件很简单,只有两行

Manifest-Version: 1.0

Created-By: 1.8.0_101 (Oracle Corporation)

1

2

添加上添加上主类属性,注意冒号后面一定要留一个空格,最后一定要多留一个换行符

Manifest-Version: 1.0

Created-By: 1.8.0_101 (Oracle Corporation)

Main-Class: Main

1

2

3

然后使用再将uncompress中所有目录、文件全部打包,注意先将原来的Main.jar删除,最后就可以运行这个新的有主类属性的Main.jar啦

rm Main.jar

jar cMf Main.jar .

java -jar Main.jar

输出:

hello world

1

2

3

4

5

6

注意上面这个jar命令使用的M选项是不生成清单,因为原本uncompress目录里就有,如果还是使用jar cf命令,生成的清单和上面第一次打包生成清单的是一样的,没有Main-Class: Main主类

rm Main.jar

jar cf Main.jar .

java -jar Main.jar

输出:

Main.jar中没有主清单属性

1

2

3

4

5

6

方法二:生成jar包的时候为其指定清单文件

还是那个方法一的uncompress目录,我们把META-INF下的MANIFEST.MF移到uncompress目录下,删除Main.jar,和META-INF目录,让uncompress中只有Main.class和MANIFEST.MF两个文件,MANIFEST.MF是有主类属性的清单文件

mv META-INF/MANIFEST .

rm Main.jar

rm -r META-INF

ls -RF

输出:

MANIFEST.MF Main.class

1

2

3

4

5

6

7

接下了指定清单文件,生成Main.jar,m选项可以指定一个清单文件

jar cmf MANIFEST.MF Main.jar Main.class

java -jar Main.jar

输出:

hello world

1

2

3

4

5

方法三:为jar包指定清单文件

还记得最早那个jardemo目录里的那个清单里没有主类的Main.jar吗,我们为它更新有主类的清单文件

jardemo/uncompress目录下的的MANIFEST.MF是有主类的,我们把它移到jardemo目录下

cd desktop/jardemo

mv uncompress/MANIFEST.MF .

rm -r uncompress

ls -RF

输出:

MANIFEST.MF Main.class  Main.jar    Main.java

1

2

3

4

5

6

7

使用u选项更新jar包,使用m选项指定清单文件,输出了一些警告信息,因为新的清单文件和Main.jar包中原来的清单信息有两个字段是重名的

jar -umf MANIFEST.MF Main.jar

输出:

三月 13, 2017 10:50:50 下午 java.util.jar.Attributes read

WARNING: Duplicate name in Manifest: Manifest-Version.

Ensure that the manifest does not have duplicate entries, and

that blank lines separate individual sections in both your

manifest and in the META-INF/MANIFEST.MF entry in the jar file.

三月 13, 2017 10:50:50 下午 java.util.jar.Attributes read

WARNING: Duplicate name in Manifest: Created-By.

Ensure that the manifest does not have duplicate entries, and

that blank lines separate individual sections in both your

manifest and in the META-INF/MANIFEST.MF entry in the jar file.

1

2

3

4

5

6

7

8

9

10

11

12

13

再运行这个jar

java -jar Main.jar

输出:

hello world

1

2

3

4

方法四:为jar更新文件,文件是清单文件

使用这个方法主要是为了再次熟悉一下u选项和理解包的概念

我们在jardemo目录里删除有主类清单的Main.jar,再次生成最早的MANIFEST.MF中没有主类的Main.jar

jar cf Main.jar Main.class

1

jar包中的MANIFEST.MF里记录了主类,而MANIFEST.MF只是jar包中的一个文件,我们将Main.jar中没有主类的MANIFEST.MF替换为有主类的MANIFEST.MF和方法三是同样的效果,首先要讲有主类的MANIFEST.MF放在合适的路径里面,我们之前看到jar包中的文件是放在META-INF目录里的,使用u来更新jar,注意需要使用M来忽视清单文件

mkdir META-INF

mv MANIFEST.MF META-INF

jar uMf Main.jar META-INF/MANIFEST.MF

java -jar Main.jar

输出:

hello world

1

2

3

4

5

6

7

三. 多个class的打包

上一节中,jarDemo目录中有Main.java和有主类信息的清单文件MANIFEST.MF,我们只保留这两个个文件,其他全部删掉,然后新建一个Say.java文件

ls -RF

输出:

META-INF/   Main.java   Say.java

./META-INF:

MANIFEST.MF

1

2

3

4

5

6

7

在新建的Say.java:

public class Say{

public static void say(String str){

System.out.println("This is " + str);

}

}

1

2

3

4

5

修改Main.java文件,让它调用Say类中的Say.say(…)方法

public class Main{

public static void main(String ... args){

System.out.println("hello world");

Say.say("Charles");

}

}

1

2

3

4

5

6

我们编译文件并打包,注意指定一个那个有主类属性的MANIFEST.MF

javac *.java

jar cmf Main.jar META-INF/MANIFEST.MF Main.class Say.class

java -jar Main.jar

输出:

hello world

This is Charles

java jar class_JAVA jar命令(一)-jar打包class文件相关推荐

  1. Java工程师常用Linux命令大全

    Java工程师常用Linux命令大全 查看目录下文件 ll 显示当前目录下文件详细信息. ll -a 显示当前目录下所有文件(包括隐藏文件) 查看当前目录 pwd 查看当前路径 查看进程 ps -a ...

  2. java命令 jar文件夹_java中jar命令打包一个文件夹下的所有文件

    (1)首先,必须保证java的所有路径都设置好,在dos提示符下输入jar -help 出现C:\Documents and Settings\dly>jar -help 非法选项:h 用法:j ...

  3. java 自带jar命令打包class文件

    我自己总结的,希望对你有帮助,(使用DOS和UltraEdit软件就行了),如果还有不明白的地方,就通过gzzgsj@126.com联系我. 生成jar文件: 1,生成类,比如名叫:Hello.cla ...

  4. 用命令行编译java并生成可执行的jar包

    1.编写源代码 编写源文件:CardLayoutDemo.java并保存,例如:I:\myApp\CardLayoutDemo.java.程序结构如下: package test;import jav ...

  5. java工程打成jar包 - 使用maven assembly插件打包及手动打包

    在java工程打包的过程中遇到过不少问题,现在总结一下.一种是典型的maven工程打包,依赖的jar包全都在pom.xml中指定,这种方式打包很方便:另一种是依赖了本机jar包(不能通过pom.xml ...

  6. java打包拆包_[Java] Java 打包成jar包 和 解压jar包

    解压jar包 jar xf xxx.jar 打包成jar包 方法一:通过jar命令 jar命令的用法: 下面是jar命令的帮助说明: 用法:jar {ctxui}[vfm0Me] [jar-file] ...

  7. java 命令行 编译 jar文件_用命令行编译java并生成可执行的jar包

    如果想用java编写一个可视化小程序,碰巧手头没有IDE的话,可以用命令行来完成编译.打包等工作. 拿自己编写的"java记事本"为例,介绍一下这个过程: 1.编写源代码. 编写源 ...

  8. java 打包后 文件资源文件 jar,JAVA打包成JAR无法找到资源文件

    源程序: package org.lza; import java.io.*; public class test{ public static void main(String[] args)thr ...

  9. java -jar命令运行jar包时指定外部依赖jar包

    大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar包的程序入口.具体的方法是修改jar包内目录META-INF下的MANIFE ...

  10. java命令执行jar包main方法指定相关依赖

    1. 准备好工程执行所需的所有依赖jar包,也可以使用maven导出依赖的方法导出: 2. 将工程打包,此处打成jar包,如上图所示,zookeeper-learn-1.0-SNAPSHOT.jar, ...

最新文章

  1. JavaWeb(一)——web服务器、Tomcat安装和配置
  2. 万字长文带你一览ICLR2020最新Transformers进展(上)
  3. Python: pip升级报错了:You are using pip version 10.0.1, however version 20.3.3 is available.
  4. redhat5.4 安装mysql_Linux redhat 5.4上安装MYDNS
  5. 【华为云技术分享】云图说 | Dubbo框架应用也可以使用Istio服务网格
  6. java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
  7. MyEclipse代码提示快捷键和常用设置
  8. Selenium应用代码(常见封装的方法二)
  9. Spring IOC整理
  10. LaTex的图文安装--TexLife+SumtraPDF+WinEdt
  11. 提高IT团队工作效率的建议
  12. xp系统怎么关闭wmi服务器,教你win10系统wmi服务器怎么关闭
  13. beyond compare 3 过期解决办法
  14. linux命令 sys,syslinux常用菜單命令
  15. [转]自定义Drawable实现灵动的红鲤鱼动画(上篇)
  16. jquery去除字符串空格
  17. 解线性方程组的各种情况
  18. 东小店南少:让你终身收益的三个营销思维,看完不再迷茫!
  19. android vitamio 函数,如何在Android Studio中集成Vitamio?
  20. “ 奋斗者耕耘论坛 ” 商业计划书 | 内卷 | 大学生创业计划书 | 大创 | 创新杯项目 | 如何财富自由 | 怎么发财 | 赚钱方法

热门文章

  1. Docker-registry + GlusterFS
  2. Java知多少(31)static关键字以及Java静态变量和静态方法
  3. 巧用层次坐标解决统计图分类轴与系列取值
  4. jbpm5.1介绍(7)
  5. 尽量用iterator代替const_iterator
  6. opsForValue() 的 set 用法
  7. mysql中to_char()和str_to_date()函数
  8. 在 Go 语言中使用 Log 包--转自GCTT
  9. 光伏行业缘何抢屋顶?
  10. 使用cookie,点击关闭一天后显示的弹窗