用java –jar 命令运行Jar包

摘要

这个技巧阐明了如何不直接处理清单文件而将一个不能运行jar包转换成一个可以执行的jar包。学会如何写一段转换jar包的程序,将你的jar包转换成你能使用java -jar 命令运行jar包或象在windows系统上那样通过双击来运行jar包。

你可以很容易地将一个应用的所有的类和资源打包到一个jar文件中去。事实上,这只是打包的一个原因。另一个原因是让用户很容易地执行包中的应用。那么在java的世界里,为什么jar是第二类公民――仅仅用作打包――当他们能成为第一类公民的时候,能和本地执行程序一样吗?

如果想执行jar文件,可以使用java命令的-jar选项。例如,你有一个可以运行的myjar.jar文件。因为该文件是可以执行的,所以你可以用如下命令执行之:java –jar myjar.jar。此外,安装在windows JRE将会把jar文件和JVM关联起来,以便通过双击来运行jar应用。

现在的问题是:如何把jar做成可以运行的包?

清单文件和主类条目

在大多数jar文件中,在目录META-INF里有个叫MANIFEST.MF的文件。在该文件中,有一个叫Main-Class的特殊条目,它说明了java -jar命令执行的类。

问题是你必须正确地在清单文件中加入这个特殊的条目――它必须是在特定的位置和特定的格式。可是,好多人不喜欢修改配置文件。

用API修改改配置

从java1.2之后,一个叫java.util.jar的包可以操作jar文件(注:它架构在java.util.zip包之上)。Jar包能让你通过Manifest类很容易地操作专门的清单文件。

让我们使用这些API写一个程序。首先,这个程序必须知道三件事:

我们想让它执行的jar文件;

我们想执行的main类(这个文件必须存在于jar包中);

我们要输出的新jar包的名称,因为不是简单地覆盖原文件;

编写代码

上面的列表将组成我们程序的参数。在这里,让我们选择一个合适名字,MakeRunnable咋样?

检查送入main的参数

假设我们的main入口是标准的main(String[])方法。我们首先应该检查程序的参数:

if (args.length != 3) {

System.out.println("Usage: MakeJarRunnable "

+ "

");

System.exit(0);

}

由于对后面的程序执行非常重要,一定要注意这个参数列表是如何解释的。参数的顺序和内容不是一成不变的;如果你改变了它们,记得要修改其它代码。

存取jar和它的清单文件

首先,我们必须创建一些知道jar和清单文件的对象:

//创建JarInputStream对象,获取它的清单

JarInputStream jarIn = new JarInputStream(new FileInputStream(args[0]));

Manifest manifest = jarIn.getManifest();

if (manifest == null) {

//如果清单不存在

manifest = new Manifest();

}

设置Main类的属性

我们把Main-Class条目放到清单文件里main属性部分。一旦我们从mainfest对象中得到这个属性集,我们就能设置合适的main类。然而,如果Main-Class属性存在于原始的JAR文件中怎么办?这个程序仅仅打印出一个警告信息并退出。或许,我们可以添加一个命令行参数告诉程序使用新值而不是使用以前的一个:

Attributes a = manifest.getMainAttributes();

String oldMainClass = a.putValue("Main-Class", args[1]);

//如果旧值存取,显示提示信息并退出

if (oldMainClass != null) {

System.out.println("Warning: old Main-Class value is: "

+ oldMainClass);

System.exit(1);

}

输出新的JAR包

我们需要创建一个新的jar文件,因此我们必须使用JarOutputStream类。注意:我们必须确保输出文件和输入文件不相同。作为可选方案,应该考虑如果两个文件同名,程序应该提示用户是否覆盖原始文件。我将这个作为练习留给读者。下面是代码。

System.out.println("Writing to " + args[2] + "...");

JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]),  manifest);

我们必须将输入jar中每一个条目写到输出jar文件中去,因此,在所有的条目上进行枚举:

//为了从输入中转移数据而创建读缓存

byte[] buf = new byte[4096];

//枚举所有条目

JarEntry entry;

while ((entry = jarIn.getNextJarEntry()) != null) {

//排除旧jar文件中的清单文件

if ("META-INF/MANIFEST.MF".equals(entry.getName())) continue;

//把条目写到输出jar文件中去

jarOut.putNextEntry(entry);

int read;

while ((read = jarIn.read(buf)) != -1) {

jarOut.write(buf, 0, read);

}

jarOut.closeEntry();

}

//刷新和关闭所有的流

jarOut.flush();

jarOut.close();

jarIn.close();

完成程序

当然,我们必须将这些代码放到一个类中的main方法中,以及引入一些需要的包。资源一节提供了完整的程序。

用法例子

让我们用一个例子说明如何使用这个程序。假设你有一个main入口在叫做HelloRunnableWorld(类全名)类之中的应用,以及你已经创建了一个叫做myjar.jar的jar包,它包含了整个应用。在这个包上运行MakeJarRunnable,如下所示:

java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar

此外,如前所述,注意我是如何安排参数列表顺序的。如果你忘记了顺序,运行一下这个不带参数的程序,它将会显示一个用法信息。

试着用java -jar命令运行myjar.jar文件,之后在myjar_r.ja文件上。注意他们的不同!完成之后,研究在每一个jar包中的清单文件(META-INF/MANIFEST.MF)。

建议:试着将MakeJarRunnable制作成一个可以运行的Jar文件!

用它处理你想运行的jar包

通过双击或者使用简单的命令运行一个jar包,总是要比把它放到 gagaghost

你可能也感兴趣:深入浅出Java多线程(1)-方法 join  什么时候用Vector, 什么时候改用ArrayList?

转载于:https://www..com/langtianya/archive/2012/09/03/2668315.html

java -jar 运行jar包_用java –jar 命令运行Jar包相关推荐

  1. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  2. java service包_利用 javaService 发布服务(jar包)

    jar在java中作为一种项目的发布形式比较普遍,往往为了容易管理更需要作为一种系统服务发布--起码服务器重启了不用人工去重新打开你所以往运行的jar文件. 这里简单的介绍下怎么将jar发布到winN ...

  3. JAVA导入Oracle包_将java的jar包导入oracle,通过oracle调用java方法

    最近项目上遇到一个问题,因为项目一些数据设计保密的问题,所以数据库的很多数据都是脱敏存储的;但是需求又需要去模糊查询,这就蛋疼了, 由于项目是用base64脱敏的;第一次想到了把条件进行脱敏之后去数据 ...

  4. java工程加包_向java工程添加jar包

    当你在向java类中导入某些包的时候(比如:import javax.servet.*)会报错,提示没有这个包.那是因为我们使用的jdk的JRE System Library库中没有包含servet_ ...

  5. was服务器里面jar包_如何在was中解决jar包冲突

    如何在 was 中解决 jar 包冲突 大型的基于 WebSphere 的项目开发中,同一个 WebSphere Application Server (以下 简称 WAS ) 上会部署多个应用程序, ...

  6. 关于java包_关于Java包

    关于java包 我希望大家都同意,类的方法应该很小,并且只有很少的依赖关系. 这种观点被广泛接受,而对"小"的解释则各不相同. 关于这一点有很多文献. 但是包裹呢? 有些人将包视为 ...

  7. java设置手机后台进程限制_让java程序在后台一直执行(例如putty关闭后后台程序继续运行)...

    如果在终端中执行java -jar xxx.jar&命令,当终端关闭时,xxx.jar也会同时结束运行,但是如果执行nohup java -jar xxx.jar&命令,则程序会在后台 ...

  8. 我的世界java版怎么加整合包_我的世界怎么制作整合包

    冗余文件的清理 既然是制作较为纯净的整合包,这一步也很关键,在前面安装forge的过程中生成了很多垃圾文件,对于强迫症来说很难受,为了精简整合包的体积,我们得将其清理清理,以下用红框标注的皆为比较重要 ...

  9. java 网络抓包_基于java的网络抓包方法

    本实验是用java实现的网络抓包程序,在windows环境下安装winpcap4.0和jpcap6.0后,下载eclipse和jigloo插件(一种在eclipse底下作图形化开发的工具),将其安装好 ...

最新文章

  1. LruCache缓存处理及异步加载图片类的封装
  2. xgboost防止过拟合
  3. 还原数据库出现“因为数据库正在使用,所以无法获得对数据库的独占访问权”解决方法-
  4. Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的
  5. [剑指offer]面试题第[65]题[JAVA][不用加减乘除做加法][位运算]
  6. AngularJS之代码风格36条建议【一】(九)
  7. mysql python 2.7.14_Python2.7.14新手学习
  8. python socket 连续send,出现粘包问题
  9. 小型企业网络规划与组建方案
  10. MATLAB局部放大
  11. 服务器lga771芯片组,LGA775主板改造用771 CPU教程
  12. 【NDN基础】Networking Named Content 全文翻译
  13. SQLServer数据库设置主键和主键自增
  14. 入门图形学:屏幕波爆特效
  15. numeric_limits
  16. 离散小波变换(DWT)
  17. mysql guanwnag_Error while deserializing binlog event at offset
  18. snowboy嵌入式_jetson nano 安装 snowboy 遇到的问题及处理
  19. SDNU 1102.小树林(水题)
  20. 下列适合作为服务器操作系统的是,江苏专转本计算机真题 含答案

热门文章

  1. 消除eslint报错
  2. scip指令集_「欧盟」SCIP数据库提交专题问答 QA
  3. c 语言字符串输入空格,C++中带空格字符串的输入问题解决
  4. 模糊推理控制系统——python
  5. if()中的continue
  6. 互联网晚报 | 10/24 星期一 | ​特斯拉降价;小鹏汽车迎来史上最大组织调整;苹果宣布加大AppStore广告推送量...
  7. 使用aliyun的registry上传下载镜像
  8. 【正一专栏】《使徒行者2》——难得追完的剧
  9. 怎么把多张照片合成一个pdf
  10. http://bbs.ichunqiu.com/thread-10048-1-1.html