Java以編程方式實現(xiàn)JAR文件的創(chuàng)建
大家好,我是指北君。
在這篇文章中,我們將介紹一下以編程方式創(chuàng)建jar文件的過程。在編寫軟件時,最終我們需要將其部署到生產(chǎn)狀態(tài)。在某些情況下,使用帶有獨立文件的classpath是可以的。通常情況下,處理一個文件會更方便。在Java的情況下,標(biāo)準(zhǔn)的方法是使用JAR、WAR或EAR文件。
基本過程是編寫清單,打開jar,添加內(nèi)容,最后保存jar。
Jar文件的解剖
jar文件是ZIP文件格式的擴(kuò)展,包含了一個清單文件。清單文件是JAR文件專用的特殊文件,可能包含各種設(shè)置。其中一些是主類、可選數(shù)據(jù)(即作者、版本等)和代碼簽名信息。
我們可以使用兼容zip的工具來查看和提取部分或全部存檔。我們還可以包括一個jars或libs子目錄,用于包含依賴性jar。由于jar是zip文件的擴(kuò)展,我們可以包括任何文件或目錄。
創(chuàng)建一個 JarTool 類
為了簡化創(chuàng)建JAR文件的過程,我們創(chuàng)建了一個單獨的、普通的舊Java對象(POJO)類,它封裝了我們的操作。我們可以將條目放入清單文件,創(chuàng)建JAR文件,添加文件或目錄。
我們還可以創(chuàng)建方法來執(zhí)行從JAR中刪除,甚至向現(xiàn)有的JAR追加條目,盡管這些操作需要完全讀取和重寫JAR。
JAR描述符
為了創(chuàng)建一個JAR文件,我們必須首先開始制定清單。
public?class?JarTool?{????
????private?Manifest?manifest?=?new?Manifest();
????public?void?startManifest()?{
????????manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION,?"1.0");
????}
}
如果我們希望jar是可執(zhí)行的,我們必須設(shè)置主類。
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文件進(jìn)行編寫
隨著清單的完成,我們現(xiàn)在可以把條目寫到JAR文件中。要做到這一點,我們必須首先打開JAR。
public?JarOutputStream?openJar(String?jarFile)?throws?IOException?{????????
????return?new?JarOutputStream(new?FileOutputStream(jarFile),?manifest);
}
將文件添加到JAR中
在向JAR中添加文件時,Java使用Solaris風(fēng)格的文件名,使用正斜杠作為分隔符(/)。注意,我們可以添加任何類型的文件,包括其他JAR文件或空目錄。這對于包括依賴關(guān)系來說真的很方便。
另外,因為JAR文件是classpath的一種形式,我們必須指定我們希望在JAR中使用絕對路徑的哪一部分。對于我們的目的,根路徑將是我們項目的classpath。
了解了這一點,我們現(xiàn)在可以用這個方法完成我們的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();
}
一個工作實例
為了證明可執(zhí)行jar的最低要求,我們將編寫一個應(yīng)用類,然后看看它是如何工作的。
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!
在這里,我們已經(jīng)編譯了每個類,然后執(zhí)行了Driver類,這將創(chuàng)建HelloWorld jar。最后,我們執(zhí)行了這個jar,結(jié)果是打印出了 "Hello World "信息。
上面的命令應(yīng)該從項目所在地執(zhí)行。
總結(jié)
在本教程中,我們看到了如何以編程方式創(chuàng)建一個jar文件,向其中添加文件,并最終執(zhí)行。
到此這篇關(guān)于Java以編程方式實現(xiàn)JAR文件的創(chuàng)建的文章就介紹到這了,更多相關(guān)Java創(chuàng)建JAR文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot+vue3無感知刷新token實戰(zhàn)教程
本文介紹了基于Spring Boot和Vue3的無感知刷新Token的實現(xiàn),包括后端token構(gòu)造和刷新邏輯,以及前端的請求處理和緩存機(jī)制2025-03-03
Java集合類的組織結(jié)構(gòu)和繼承、實現(xiàn)關(guān)系詳解
這篇文章主要介紹了Java集合類的組織結(jié)構(gòu)和繼承、實現(xiàn)關(guān)系,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
什么是Maven及如何配置國內(nèi)源實現(xiàn)自動獲取jar包的操作
本文介紹了Maven的基本概念,包括項目構(gòu)建、依賴管理、倉庫管理以及如何設(shè)置國內(nèi)源,通過Maven,開發(fā)者可以自動化管理項目的依賴和構(gòu)建流程,提高開發(fā)效率,感興趣的朋友跟隨小編一起看看吧2024-11-11
SpringBoot+SpringSecurity實現(xiàn)基于真實數(shù)據(jù)的授權(quán)認(rèn)證
Spring Security是一個功能強(qiáng)大且高度可定制的身份驗證和訪問控制框架,Spring Security主要做兩個事情,認(rèn)證、授權(quán)。這篇文章主要介紹了SpringBoot+SpringSecurity實現(xiàn)基于真實數(shù)據(jù)的授權(quán)認(rèn)證,需要的朋友可以參考下2021-05-05

