如何使用Golang打包jar應(yīng)用
背景
想把自己的一個(gè)SpringBoot應(yīng)用打包成可執(zhí)行文件。看看Golang是如何做到的。
Go 的 go:embed 功能介紹與打包 JAR 文件示例
go:embed
是 Go 1.16 引入的一個(gè)強(qiáng)大功能,它允許在編譯時(shí)將外部文件或目錄嵌入到 Go 程序中。下面介紹如何使用 go:embed
來嵌入 JAR 文件。
1. go:embed 基礎(chǔ)介紹
基本特性
- 編譯時(shí)嵌入文件內(nèi)容
- 支持嵌入單個(gè)文件、多個(gè)文件或整個(gè)目錄
- 支持三種嵌入類型:
string
- 用于文本文件[]byte
- 用于二進(jìn)制文件embed.FS
- 用于文件系統(tǒng)(支持多個(gè)文件/目錄)
基本語法
import "embed" //go:embed filename.txt var fileContent string //go:embed image.png var imageData []byte //go:embed templates/* var templatesFS embed.FS
2. 嵌入 JAR 文件示例
假設(shè)你有一個(gè)需要嵌入的 app.jar
文件,以下是完整示例:
項(xiàng)目結(jié)構(gòu)
project/ ├── embedded/ │ └── app.jar # 要嵌入的JAR文件 ├── main.go └── go.mod
代碼實(shí)現(xiàn)
package main import ( "embed" "io" "log" "os" "path/filepath" ) //go:embed embedded/app.jar var jarFile []byte func main() { // 指定輸出路徑(可以是臨時(shí)目錄或特定位置) outputPath := filepath.Join(os.TempDir(), "app.jar") // 將嵌入的JAR寫入文件系統(tǒng) err := os.WriteFile(outputPath, jarFile, 0755) if err != nil { log.Fatalf("Failed to write JAR file: %v", err) } log.Printf("JAR file extracted to: %s", outputPath) // 現(xiàn)在你可以使用這個(gè)JAR文件,比如通過exec.Command運(yùn)行它 // exec.Command("java", "-jar", outputPath) }
3. 高級(jí)用法:嵌入多個(gè)文件或目錄
如果你有多個(gè) JAR 文件需要嵌入:
//go:embed embedded/*.jar var jarFiles embed.FS func main() { // 列出所有嵌入的JAR文件 entries, err := jarFiles.ReadDir("embedded") if err != nil { log.Fatal(err) } // 提取所有JAR文件 for _, entry := range entries { if filepath.Ext(entry.Name()) == ".jar" { data, err := jarFiles.ReadFile("embedded/" + entry.Name()) if err != nil { log.Printf("Failed to read %s: %v", entry.Name(), err) continue } outputPath := filepath.Join(os.TempDir(), entry.Name()) err = os.WriteFile(outputPath, data, 0755) if err != nil { log.Printf("Failed to write %s: %v", entry.Name(), err) continue } log.Printf("Extracted %s to %s", entry.Name(), outputPath) } } }
4. 使用注意事項(xiàng)
路徑規(guī)則:
go:embed
路徑是相對(duì)于包含該指令的Go源文件的- 不能包含
.
或..
等路徑組件 - 不能匹配到父目錄中的文件
文件大小限制:
- Go 1.16+ 對(duì)嵌入文件大小沒有硬性限制
- 但非常大的文件可能會(huì)增加編譯時(shí)間和二進(jìn)制大小
構(gòu)建約束:
- 嵌入的文件必須在構(gòu)建時(shí)可用
- 如果文件不存在,構(gòu)建會(huì)失敗
安全考慮:
- 提取嵌入文件時(shí)要注意目標(biāo)路徑的權(quán)限
- 考慮使用臨時(shí)目錄并在程序退出時(shí)清理
5. 實(shí)際應(yīng)用場景
- 打包Java應(yīng)用:將依賴的JAR文件嵌入Go程序,然后通過
exec.Command
調(diào)用Java運(yùn)行 - 嵌入式數(shù)據(jù)庫:如SQLite數(shù)據(jù)庫文件
- Web服務(wù)器資源:HTML/CSS/JS等前端資源
- 配置文件:默認(rèn)配置模板
6. 完整示例:運(yùn)行嵌入的JAR
package main import ( "embed" "log" "os" "os/exec" "path/filepath" ) //go:embed app.jar var jarFile []byte func main() { // 創(chuàng)建臨時(shí)文件 tmpFile, err := os.CreateTemp("", "embedded-*.jar") if err != nil { log.Fatal(err) } defer os.Remove(tmpFile.Name()) // 程序退出時(shí)刪除 // 寫入JAR內(nèi)容 if _, err := tmpFile.Write(jarFile); err != nil { log.Fatal(err) } if err := tmpFile.Close(); err != nil { log.Fatal(err) } // 執(zhí)行Java命令 cmd := exec.Command("java", "-jar", tmpFile.Name()) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr log.Println("Starting Java application...") if err := cmd.Run(); err != nil { log.Fatalf("Java application failed: %v", err) } }
通過這種方式,你可以將Java應(yīng)用程序打包到Go二進(jìn)制文件中,然后通過Go程序來分發(fā)和啟動(dòng)它。
到此這篇關(guān)于使用Golang打包jar應(yīng)用的文章就介紹到這了,更多相關(guān)Golang打包jar應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- golang 項(xiàng)目打包部署環(huán)境變量設(shè)置方法
- Golang打包go項(xiàng)目部署到linux服務(wù)器正確方法
- intelliJ?idea安裝go開發(fā)環(huán)境并搭建go項(xiàng)目(打包)全過程
- Django項(xiàng)目打包完整步驟以及可能出現(xiàn)的問題
- golang打包成帶圖標(biāo)的exe可執(zhí)行文件
- go項(xiàng)目打包部署的完整步驟
- goland把go項(xiàng)目打包進(jìn)docker鏡像的全過程記錄
- Golang打包配置文件的實(shí)現(xiàn)示例
- Go打包二進(jìn)制文件的實(shí)現(xiàn)
相關(guān)文章
Golang實(shí)現(xiàn)秒讀32GB大文件示例步驟
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)秒讀32GB大文件的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器
Golang多線程爬蟲是一種高效抓取大量數(shù)據(jù)的利器。Golang語言天生支持并發(fā)和多線程,可以輕松實(shí)現(xiàn)多線程爬蟲的開發(fā)。通過使用Golang的協(xié)程和通道,可以實(shí)現(xiàn)爬蟲的高效并發(fā)抓取、數(shù)據(jù)處理和存儲(chǔ)2023-05-05Go 類型轉(zhuǎn)化工具庫cast函數(shù)詳解
這篇文章主要介紹了Go 類型轉(zhuǎn)化工具庫cast函數(shù)詳解,cast 是在Github上開源的工具庫,就像他的名字一樣,他為我們提供了非常便捷的類型轉(zhuǎn)化的方法2022-07-07go語言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐
MQTT是一個(gè)基于客戶端-服務(wù)器的消息發(fā)布/訂閱傳輸協(xié)議。本文主要介紹了go語言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09