Java 以编程方式创建JAR文件

开发 前端
为了简化创建JAR文件的过程,我们创建了一个单独的、普通的旧Java对象(POJO)类,它封装了我们的操作。我们可以将条目放入清单文件,创建JAR文件,添加文件或目录。

大家好,我是指北君。

在这篇文章中,我们将介绍一下以编程方式创建jar文件的过程。在编写软件时,最终我们需要将其部署到生产状态。在某些情况下,使用带有独立文件的classpath是可以的。通常情况下,处理一个文件会更方便。在Java的情况下,标准的方法是使用JAR、WAR或EAR文件。

基本过程是编写清单,打开jar,添加内容,最后保存jar。

Jar文件的解剖

jar文件是ZIP文件格式的扩展,包含了一个清单文件。清单文件是JAR文件专用的特殊文件,可能包含各种设置。其中一些是主类、可选数据(即作者、版本等)和代码签名信息。

我们可以使用兼容zip的工具来查看和提取部分或全部存档。我们还可以包括一个jars或libs子目录,用于包含依赖性jar。由于jar是zip文件的扩展,我们可以包括任何文件或目录。

创建一个 JarTool 类

为了简化创建JAR文件的过程,我们创建了一个单独的、普通的旧Java对象(POJO)类,它封装了我们的操作。我们可以将条目放入清单文件,创建JAR文件,添加文件或目录。

我们还可以创建方法来执行从JAR中删除,甚至向现有的JAR追加条目,尽管这些操作需要完全读取和重写JAR。

JAR描述符

为了创建一个JAR文件,我们必须首先开始制定清单。

public class JarTool {    
private Manifest manifest = new Manifest();

public void startManifest() {
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
}
}

如果我们希望jar是可执行的,我们必须设置主类。

public void setMainClass(String mainFQCN) {
if (mainFQCN != null && !mainFQCN.equals("")) {
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, mainFQCN);
}
}

另外,如果我们想指定额外的属性,我们可以把它们添加到清单中,比如说。

addToManifest("Can-Redefine-Classes", "true");

下面是这个方法。

public void addToManifest(String key, String value) {
manifest.getMainAttributes().put(new Attributes.Name(key), value);
}

打开JAR文件进行编写

随着清单的完成,我们现在可以把条目写到JAR文件中。要做到这一点,我们必须首先打开JAR。

public JarOutputStream openJar(String jarFile) throws IOException {        
return new JarOutputStream(new FileOutputStream(jarFile), manifest);
}

将文件添加到JAR中

在向JAR中添加文件时,Java使用Solaris风格的文件名,使用正斜杠作为分隔符(/)。注意,我们可以添加任何类型的文件,包括其他JAR文件或空目录。这对于包括依赖关系来说真的很方便。

另外,因为JAR文件是classpath的一种形式,我们必须指定我们希望在JAR中使用绝对路径的哪一部分。对于我们的目的,根路径将是我们项目的classpath。

了解了这一点,我们现在可以用这个方法完成我们的JarTool类。

public void addFile(JarOutputStream target, String rootPath, String source) 
throws FileNotFoundException, IOException {
String remaining = "";
if (rootPath.endsWith(File.separator)) {
remaining = source.substring(rootPath.length());
} else {
remaining = source.substring(rootPath.length() + 1);
}
String name = remaining.replace("\\","/");
JarEntry entry = new JarEntry(name);
entry.setTime(new File(source).lastModified());
target.putNextEntry(entry);

BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true) {
int count = in.read(buffer);
if (count == -1) {
break;
}
target.write(buffer, 0, count);
}
target.closeEntry();
in.close();
}

一个工作实例

为了证明可执行jar的最低要求,我们将编写一个应用类,然后看看它是如何工作的。

public class Driver {
public static void main(String[] args) throws IOException {
JarTool tool = new JarTool();
tool.startManifest();
tool.addToManifest("Main-Class", "com.javanorth.createjar.HelloWorld");

JarOutputStream target = tool.openJar("HelloWorld.jar");

tool.addFile(target, System.getProperty("user.dir") + "\\src\\main\\java",
System.getProperty("user.dir") + "\\src\\main\\java\\com\\javanorth\\createjar\\HelloWorld.class");
target.close();
}
}

HelloWorld类是一个非常简单的类,只有一个main()方法可以打印出文本。

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}

为了证明它的作用,我们有这个例子。

$ javac -cp src/main/java src/main/java/com/javanorth/createjar/HelloWorld.java
$ javac -cp src/main/java src/main/java/com/javanorth/createjar/JarTool.java
$ javac -cp src/main/java src/main/java/com/javanorth/createjar/Driver.java
$ java -cp src/main/java com/javanorth/createjar/Driver
$ java -jar HelloWorld.jar
Hello World!

在这里,我们已经编译了每个类,然后执行了Driver类,这将创建HelloWorld jar。最后,我们执行了这个jar,结果是打印出了 "Hello World "信息。

上面的命令应该从项目所在地执行。

总结

在本教程中,我们看到了如何以编程方式创建一个jar文件,向其中添加文件,并最终执行。

责任编辑:武晓燕 来源: Java技术指北
相关推荐

2013-03-08 02:46:00

个人开发APP

2009-04-03 13:45:29

JavaiTextPDF

2010-04-13 08:49:08

JavaLombokJavabean

2020-08-28 09:40:51

Java开发代码

2011-07-11 08:59:51

PHP

2021-08-02 11:13:28

人工智能机器学习技术

2020-11-28 19:37:03

MeldLinuxdiff命令

2016-02-23 09:23:32

2019-12-12 10:46:15

Kubernetes容器系统

2020-01-15 13:50:29

桌面快捷方式Windows 10WiFi网络

2021-02-27 16:08:17

Java异步非阻塞

2009-10-23 09:02:52

Linux系统安装卸载文件操作系统

2018-08-19 09:45:19

Windows 10蓝屏死机转储文件

2022-04-27 09:39:11

Mixin工具

2012-09-17 10:35:41

JavaScriptJS代码

2020-08-18 10:04:49

大数据数据架构技术

2010-01-25 17:33:25

Android Men

2010-03-18 15:31:13

Java创建线程

2009-06-18 12:37:26

java编程语言

2022-12-30 11:05:40

Rust代码
点赞
收藏

51CTO技术栈公众号