背景
想把自己的一个springboot应用打包成可执行文件。看看golang是如何做到的。
go 的 go:embed 功能介绍与打包 jar 文件示例
go:embed 是 go 1.16 引入的一个强大功能,它允许在编译时将外部文件或目录嵌入到 go 程序中。下面介绍如何使用 go:embed 来嵌入 jar 文件。
1. go:embed 基础介绍
基本特性
- 编译时嵌入文件内容
- 支持嵌入单个文件、多个文件或整个目录
- 支持三种嵌入类型:
string- 用于文本文件[]byte- 用于二进制文件embed.fs- 用于文件系统(支持多个文件/目录)
基本语法
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 文件示例
假设你有一个需要嵌入的 app.jar 文件,以下是完整示例:
项目结构
project/ ├── embedded/ │ └── app.jar # 要嵌入的jar文件 ├── main.go └── go.mod
代码实现
package main
import (
"embed"
"io"
"log"
"os"
"path/filepath"
)
//go:embed embedded/app.jar
var jarfile []byte
func main() {
// 指定输出路径(可以是临时目录或特定位置)
outputpath := filepath.join(os.tempdir(), "app.jar")
// 将嵌入的jar写入文件系统
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)
// 现在你可以使用这个jar文件,比如通过exec.command运行它
// exec.command("java", "-jar", outputpath)
}3. 高级用法:嵌入多个文件或目录
如果你有多个 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. 使用注意事项
路径规则:
go:embed路径是相对于包含该指令的go源文件的- 不能包含
.或..等路径组件 - 不能匹配到父目录中的文件
文件大小限制:
- go 1.16+ 对嵌入文件大小没有硬性限制
- 但非常大的文件可能会增加编译时间和二进制大小
构建约束:
- 嵌入的文件必须在构建时可用
- 如果文件不存在,构建会失败
安全考虑:
- 提取嵌入文件时要注意目标路径的权限
- 考虑使用临时目录并在程序退出时清理
5. 实际应用场景
- 打包java应用:将依赖的jar文件嵌入go程序,然后通过
exec.command调用java运行 - 嵌入式数据库:如sqlite数据库文件
- web服务器资源:html/css/js等前端资源
- 配置文件:默认配置模板
6. 完整示例:运行嵌入的jar
package main
import (
"embed"
"log"
"os"
"os/exec"
"path/filepath"
)
//go:embed app.jar
var jarfile []byte
func main() {
// 创建临时文件
tmpfile, err := os.createtemp("", "embedded-*.jar")
if err != nil {
log.fatal(err)
}
defer os.remove(tmpfile.name()) // 程序退出时删除
// 写入jar内容
if _, err := tmpfile.write(jarfile); err != nil {
log.fatal(err)
}
if err := tmpfile.close(); err != nil {
log.fatal(err)
}
// 执行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应用程序打包到go二进制文件中,然后通过go程序来分发和启动它。
到此这篇关于使用golang打包jar应用的文章就介绍到这了,更多相关golang打包jar应用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论