目录

使用Golang打包jar应用

文章目录

  • 背景
  • [Go 的 go:embed 功能介绍与打包 JAR 文件示例](#Go 的 go:embed 功能介绍与打包 JAR 文件示例)
    • [1. go:embed 基础介绍](#1. go:embed 基础介绍)
    • [2. 嵌入 JAR 文件示例](#2. 嵌入 JAR 文件示例)
    • [3. 高级用法:嵌入多个文件或目录](#3. 高级用法:嵌入多个文件或目录)
    • [4. 使用注意事项](#4. 使用注意事项)
    • [5. 实际应用场景](#5. 实际应用场景)
    • [6. 完整示例:运行嵌入的JAR](#6. 完整示例:运行嵌入的JAR)

背景

想把自己的一个SpringBoot应用打包成可执行文件。看看Golang是如何做到的。

Go 的 go:embed 功能介绍与打包 JAR 文件示例

go:embed 是 Go 1.16 引入的一个强大功能,它允许在编译时将外部文件或目录嵌入到 Go 程序中。下面介绍如何使用 go:embed 来嵌入 JAR 文件。

1. go:embed 基础介绍

基本特性

  • 编译时嵌入文件内容
  • 支持嵌入单个文件、多个文件或整个目录
  • 支持三种嵌入类型:
    • string - 用于文本文件
    • []byte - 用于二进制文件
    • embed.FS - 用于文件系统(支持多个文件/目录)

基本语法

go 复制代码
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

代码实现

go 复制代码
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 复制代码
//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. 使用注意事项

  1. 路径规则

    • go:embed 路径是相对于包含该指令的Go源文件的
    • 不能包含 ... 等路径组件
    • 不能匹配到父目录中的文件
  2. 文件大小限制

    • Go 1.16+ 对嵌入文件大小没有硬性限制
    • 但非常大的文件可能会增加编译时间和二进制大小
  3. 构建约束

    • 嵌入的文件必须在构建时可用
    • 如果文件不存在,构建会失败
  4. 安全考虑

    • 提取嵌入文件时要注意目标路径的权限
    • 考虑使用临时目录并在程序退出时清理

5. 实际应用场景

  1. 打包Java应用 :将依赖的JAR文件嵌入Go程序,然后通过exec.Command调用Java运行
  2. 嵌入式数据库:如SQLite数据库文件
  3. Web服务器资源:HTML/CSS/JS等前端资源
  4. 配置文件:默认配置模板

6. 完整示例:运行嵌入的JAR

go 复制代码
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程序来分发和启动它。

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
明月看潮生2 分钟前
青少年编程与数学 02-016 Python数据结构与算法 20课题、几何算法
python·算法·青少年编程·编程与数学
ErizJ43 分钟前
Golang|Kafka在秒杀场景中的应用
开发语言·分布式·后端·golang·kafka
limengshi13839244 分钟前
使用Python+xml+shutil修改目标检测图片和对应xml标注文件
xml·python·目标检测
飞川撸码1 小时前
【LeetCode 热题100】二叉树构造题精讲:前序 + 中序建树 & 有序数组构造 BST(力扣105 / 108)(Go语言版)
数据结构·leetcode·golang·二叉树
计算机徐师兄1 小时前
Python基于Django的房屋信息可视化及价格预测系统(附源码,文档说明)
python·房屋信息可视化·房屋价格预测系统·房屋价格预测·房屋分析·python房屋信息可视化系统·python房屋价格预测系统
木觞清1 小时前
使用Python爬取豆瓣电影Top250并保存到Excel完整教程
开发语言·python
Start_Present1 小时前
Pytorch 第十五回:神经网络编码器——GAN生成对抗网络
pytorch·python·神经网络·生成对抗网络·数据分析
水w2 小时前
【Python爬虫】简单案例介绍3
开发语言·爬虫·python·scrapy·beautifulsoup
weixin_307779132 小时前
Python Pandas实现导出两个Excel数据集的分组记录数分析
开发语言·python·pandas
陌漠ardently2 小时前
正则表达式和excel文件保存(python)
python·mysql·excel