制作可执行JAR

原创 2002年07月01日 09:39:00

200年5月10号
作者:Shawn Silverman 翻译:Sean

摘要
本文阐述了如何把一个不可执行的JAVA Archive(JAR)文件变成可执行,而不用直接操作manifest文件。你会学到写出短小的一个程序,通过运行java -jar命令或在像windows一样的操作系统里面用双击鼠标运行任何JAR文件。

你可以很容易地把应用程序的一整套class文件和资源文件打包到一个JAR中。事实上这就是jar文件存在的一个目的。另外一个目的就是让用户能很容易地执行被打包到jar文件里面的应用程序。那么为什么jar文件仅仅作为文件在整个java里面占据了次要的地位,而本地执行则被忽视?

要执行一个jar文件,你可以使用java命令的-jar选项。举一个例子来说,假如你有个名叫myjar.jar的文件。这个jar是可以运行的,你可以运行它:java -jar myjar.jar.另外一个办法就是,当Java Runtime Environment(JRE)已经被安装到一个像windows的操作系统上,将jar文件与JVM关联(关联java.exe跟jar文件)在一起你就可以通过双击jar来运行这个应用程序。当然,jar文件必须是可执行的。
现在的问题是:如何做一个可以执行的jar?

manifest文件以及Main-class入口
在大多数jar中,都在一个叫META-INF的目录里面保存了一个叫MANIFEST.MF的文件。那个文件里面,
包含了一个特殊表项名字叫Main-Class,告诉java -jar命令应该执行哪个class.

问题是你必须为manifest文件手工加入适当表项,而且必须在一定的位置和用一定的格式。不幸的是,不是每个人都喜欢打开写字板编辑配置文件。

让API帮你完成任务
自从java1.2发布以来,一个叫java.uil.jar包的出现,让你能够方便处理jar文件。
(注意:该包基于java.util.zip)特别地,jar包让你通过Mainfest类,可以容易操作
那些manifest文件.

就让我们用这个API写一个程序吧。首先,这个程序必须知道三样东西:
1。我们要使之可运行的jar文件。
2。运行jar的主类(这个类必须包含在jar中)。
3。输出新jar文件的文件名,因为我们不能简单地覆盖原来的文件。

编写程序
上面列表的三点要求将组成我们的程序的参数。现在,让我们为这个程序选择一个适当的名字。
MakeJarRunnable听起来觉得怎样?

为main方法检查参数
假设我们的main方法入口点是一个标准的main(String[])方法。我们应该这样检查程序的参数:
  if (args.length != 3) {
     System.out.println("Usage: MakeJarRunnable "
                        + "<jar file> <Main-Class><output>");
     System.exit(0);
  }
  请注意参数列表是如何描述的,因为这在以下代码中是很重要的。参数的次序和内容不是固定的;
  然而,如果你要改变他们的话,要记住响应修改其他代码。

  访问jar和jar的manifest文件
  第一,我们必须创建一些了解jar和manifest的对象:
    //Create the JarInputStream object, and get its manifest
    JarInputStream jarIn = new JarInputStream(new FileInputStream(args[0]));
    Manifest manifest = jarIn.getManifest();
    if (manifest == null) {
        //This will happen if no manifest exists

        manifest = new Manifest();
    }

设置Main-Class属性
我们把Main-Class入口放到manifest文件的main属性部分。一旦从manifest对象获得这个属性,就可以设置需要的main class。然而,如果main-Class属性已经存在原来的jar当中又如何呢?这里我们只是简单地输出一个警告然后退出。我们能加入一个命令行参数告诉程序使用新的值,而代替了旧的那个:
    Attributes a = manifest.getMainAttributes();
    String oldMainClass = a.putValue("Main-Class", args[1]);

    //If an old value exists, tell the user and exit

    if (oldMainClass != null) {
        System.out.println("Warning: old Main-Class value is: "
                           + oldMainClass);
        System.exit(1);
    }

    输出新的JAR
    我们需要创建一个新的JAR文件,所以我们必须使用JarOutputStream类。注意:
    我们必须确定我们不用跟输入文件相同的名字作为输出文件的名字。还有一个方案就是,
    程序应该考虑到一种情况,就是两个jar文件都是相同的,促使用户覆盖原来的文件,如果
    他愿意这么做的话。然而,我在保留了这一点,作为读者的一个练习。从如下代码开始:
    System.out.println("Writing to " + args[2] + "...");
    JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]),
                                                 manifest);
    我们必须从输入JAR写每个表项到输出的JAR,所以迭代每个表项:
        //Create a read buffer to transfer data from the input

    byte[] buf = new byte[4096];

    //Iterate the entries

    JarEntry entry;
    while ((entry = jarIn.getNextJarEntry()) != null) {
        //Exclude the manifest file from the old JAR

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

        //Write the entry to the output JAR

        jarOut.putNextEntry(entry);
        int read;
        while ((read = jarIn.read(buf)) != -1) {
            jarOut.write(buf, 0, read);
        }

        jarOut.closeEntry();
    }

    //Flush and close all the streams

    jarOut.flush();
    jarOut.close();

    jarIn.close();

    完成程序
    当然,我们必须把这些代码放到一个类的main方法里面,并且需要一大堆import代码。完整程序:
    http://www.javaworld.com/javaworld/javatips/javatip127/MakeJarRunnable.zip

    程序使用例子
    让我们把这个程序应用到一个例子里面来。假设你有一个应用程序,该程序的入口点是一个叫HelloRunnableWorld的 类,再假设你已经创建了一个jar叫myjar.jar,包含了整个程序。运行MakeJarRunnable:
    java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar
    正如前面提到的,注意一下我的参数顺序。如果你忘记了顺序,没有参数运行一下程序,它会响应出现一个 用法提示信息。

    尝试对myjar.jar运行java -jar命令。然后对myjar_r.jar。注意区别不同!好了,你完成了这一切了,  浏览一下每个jar的manifest文件(META-INF/MANIFEST.MF)

 

eclipse生成【带有外部jar包】的java可执行jar包

之前有写过一篇使用eclipse生成java可执行jar包,但是最近的一次使用中无论如何都不成功,当双击执行打成的jar时,弹出如下错误:could not find the main class:m...
  • tuzongxun
  • tuzongxun
  • 2016年06月15日 10:42
  • 6852

Maven打包可执行Jar的集中方法

一、无依赖其他任何jar org.apache.maven.plugins maven-...
  • amorym
  • amorym
  • 2016年07月12日 09:32
  • 2191

Java_Java项目如何生成可执行jar包、exe文件;

功能:为大家浅谈如何通过eJava项目生成
  • u011168154
  • u011168154
  • 2014年10月21日 11:34
  • 5745

Maven总结(一)Maven构建可执行的jar包

Maven构建可执行的jar包
  • birdben
  • birdben
  • 2016年07月07日 05:48
  • 4830

使用eclipse创建java程序可执行jar包

一、eclipse中,在要打成jar包的项目名上右击,出现如下弹出框,选择“export”: 二、在接下来出现的界面中点击“jar file”,然后next: 三、在接下来出现的界...
  • tuzongxun
  • tuzongxun
  • 2015年12月18日 09:55
  • 1509

Maven打包可执行Jar的几种方法

一、无依赖其他任何jar org.apache.maven.plugins maven-j...
  • xiaojiesu
  • xiaojiesu
  • 2016年07月11日 23:02
  • 11255

制作可执行jar文件包

使用jar.exe命令生成jar文件包的用法和参数说明如下: 编写一个java文件并编译: 编写一个清单文件manifest.mf,执行命令生成jar文件包,执行 java -jar (your...
  • Kenbode
  • Kenbode
  • 2016年12月01日 12:27
  • 102

浅谈java 中构建可执行 jar 包的几种方式

概述       有时候,由于项目的需要,我们会将源码编译后以工具包(即将class打成jar包)的形式对外提供,此时,你的 jar 包不一定要是可执行的,只要能通过编译,能被别的项目以 imp...
  • a616413086
  • a616413086
  • 2016年10月13日 16:16
  • 3274

Eclipse导出可运行的jar包并运行

Eclipse导入可运行的jar包并运行 一、导出可运行的jar 第一步:右击项目选择Export导出,在弹出的窗口中选择'Java',接着选择'Runnable JAR file'。如下图: ...
  • kpchen_0508
  • kpchen_0508
  • 2015年10月20日 11:46
  • 9803

eclipse打包成可运行.jar文件

问题背景因为之前一直在开发测试安卓,没有涉足PC平台,一般的java程序也是直接在ecplise中编辑完成后,直接运行的,没有进行过其他考虑,现在因为要用云或者虚拟机进行程序调用,这样直接在ecpli...
  • weiqiang_1989
  • weiqiang_1989
  • 2016年10月12日 17:22
  • 3402
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:制作可执行JAR
举报原因:
原因补充:

(最多只允许输入30个字)