`

用java API制作可执行JAR文件

阅读更多

作者: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代码。完整程序:

程序使用例子
让我们把这个程序应用到一个例子里面来。假设你有一个应用程序,该程序的入口点是一个叫HelloRunnableWorld的 类,再假设你已经创建了一个jar叫myjar.jar,包含了整个程序。运行MakeJarRunnable:

c:\java>java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar

运行结果:

c:\java>Hello, Runnable World!

正如前面提到的,注意一下我的参数顺序。如果你忘记了顺序,没有参数运行一下程序,它会响应出现一个用法提示信息。

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

分享到:
评论

相关推荐

    java动态编译指定java文件且将java文件生成jar

    在Java编程中,有时我们需要在运行时动态地编译源代码文件,并将其打包成可执行的JAR(Java Archive)文件。这样的需求通常出现在我们希望根据用户输入或特定条件生成并执行新的代码逻辑时。本教程将深入讲解如何...

    hbase java api 所需最精简 jar

    使用这些JAR文件,开发者可以在Java代码中创建HBase连接,定义表结构,插入、查询和更新数据,以及执行扫描操作。通过编写适当的方法和逻辑,可以构建高效的数据处理应用。然而,值得注意的是,精简版的JAR包可能不...

    15分钟学会MyEclipse导出jar文件再装换成exe可执行文件

    在本文中,我们将探讨如何使用 MyEclipse 导出 jar 文件,并将其转换成 exe 可执行文件。这个过程将分为四个步骤:导出 jar 文件、运行 jar 文件、连同第三方文件一并导出至 jar 文件、将 jar 文件转换成 exe 可执行...

    jar文件 变成dll

    标题中的“jar文件变成dll”指的是将Java编写的类库转换为.NET平台可使用的动态链接库(DLL)文件。在.NET框架中,DLL是共享代码的主要形式,可以在多个应用程序之间重用。Java的jar文件则包含了编译后的字节码,...

    JAVA_API1.6文档(中文)

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    Java 自动加载JAR文件并运行其中的类方法

    它是一个归档文件格式,包含了一个或多个.class文件,这些文件构成了Java应用程序的可执行代码。JAR文件可以包含一个清单(MANIFEST.MF)文件,用于指定启动类和其他元数据。 要自动加载JAR文件并运行其中的类方法...

    javax.servlet-api-3.1.0.jar javax.el-api-2.2.4.jar javax.el-2.2.4.jar

    综上所述,`javax.servlet-api-3.1.0.jar`, `javax.el-api-2.2.4.jar`, `javax.el-2.2.4.jar`这些文件对于构建基于Java的Web应用程序至关重要,它们提供了与Web服务器通信和处理用户请求的核心功能,同时也支持高效...

    Java8/java1.8的tools.jar

    3. **JAR打包工具API**:允许开发者创建、修改和提取JAR文件,这对于构建和部署Java应用程序是必不可少的。 4. **Java代理API**:支持Java代理(Java Proxy),使得在运行时可以动态地拦截和修改方法调用。 5. **...

    jarjar-方便Java打包工具,自定义修改jar包包名

    Java开发过程中,打包工具起着至关重要的作用,它们帮助开发者将源代码编译、整合资源并打包成可执行的JAR文件。其中,"jarjar"是一个非常实用的工具,专为Java程序员设计,用于方便地对JAR文件进行操作,如重命名类...

    网络蚂蚁java版本(源码及可执行jar文件)

    本资源提供的是网络蚂蚁的Java版本,包含源码及可执行的jar文件,对于学习Java编程、多线程下载策略以及网络编程的开发者来说,这是一个宝贵的参考资料。 首先,我们来了解一下Java语言在网络编程中的应用。Java...

    java文件上传下载jar包

    7. **安全性**:文件上传下载时,需要注意安全问题,如防止文件覆盖、拒绝执行可执行文件、限制文件类型和大小等,以避免恶意文件的上传和传播。 8. **性能优化**:为了提升用户体验,可以采用分块上传和下载、断点...

    jspsmartupload(api+jar) 文件上传API+JAR包

    **JSpsmartupload API + JAR 文件上传技术详解** 在Web开发中,文件上传功能是一项常见且重要的需求。JSpsmartupload 是一个基于Java的文件上传组件,它为开发者提供了简单易用的API,使得在JSP环境中实现文件上传...

    java集成kettle所有jar包

    6. **打包和部署**:将Java应用打包成可执行的JAR或WAR文件,然后部署到目标环境,如本地服务器、云平台等。 最后,记住Kettle的版本更新可能带来API的变化,因此保持你的Kettle版本与Java项目同步是很重要的。定期...

    java连数据库3个jar文件

    这些jar(Java Archive)文件通常包含了驱动程序和相关API,使得Java程序能够通过JDBC(Java Database Connectivity)接口与各种类型的数据库进行通信。在提供的描述中,我们并没有明确的数据库类型,但根据给出的...

    jsp-api.jar 在使用jsp时导入的jar包

    **标签解析:**"jar" 和 "java" 这两个标签强调了该资源与Java平台的可执行文件格式(jar)以及Java编程语言相关。"jar" 文件是Java应用程序的归档文件,它集合了类、资源和其他文件,便于部署和执行。"java" 指的是...

    weblogic.jar/wlclient.jar/wls-api.jar相关jar包

    使用这些JAR文件时,确保它们与所使用的WebLogic Server版本兼容非常重要,因为不同版本的WebLogic Server可能会有API的变化或不兼容性。同时,需要注意的是,直接引用服务器目录下的JAR包可能在部署时带来问题,...

    javax.servlet-api-3.1.0.jar

    总的来说,`javax.servlet-api-3.1.0.jar`是Java Web开发的基础,它定义了与Web服务器交互的标准,使得开发者能够构建强大的、可扩展的Web应用程序。理解和掌握Servlet API的原理和使用方法,是每个Java Web开发者...

    Java项目制作可执行程序与安装程序.rar

    为了将Java项目转换为Windows平台下的EXE可执行程序,我们借助了Exe4j工具,而Inno Setup则用于制作安装程序。以下是这些工具和技术的详细介绍: 1. **JavaFX**:JavaFX是一个用于构建桌面、移动和嵌入式设备的富...

    mysql-connector-java-8.0.11.jar文件

    MySQL Connector/J是MySQL数据库与Java应用程序之间的桥梁,它是...总的来说,`mysql-connector-java-8.0.11.jar`是开发Java应用与MySQL数据库交互不可或缺的组件,它的正确使用能够帮助开发者高效地完成数据操作任务。

    javax.servlet-api-4.0.1.jar

    3. **部署和使用**:将TLD和对应的Java类打包到一个JAR文件中,并在Web应用的WEB-INF目录下放置TLD。在JSP页面中,通过`&lt;jsp:useBean&gt;`或`&lt;jsp:taglib&gt;`指令引入标签库,然后就可以在页面中自由使用自定义标签了。 ...

Global site tag (gtag.js) - Google Analytics