将 Jar 包构建为 AppImage 可执行文件

如果你有一个 Jar 包,想要分发到服务器/客户/桌面等环境,但是又不想这些环境去配置 Java 环境该怎么办呢。本文章将介绍如何将一个 Jar 包打包成 Linux 的通用可执行文件:AppImage。

1.AppImage 介绍

AppImage 是一种通用的 Linux 应用打包格式,旨在简化软件分发和安装过程。它允许开发者将应用程序及其所有依赖项打包成一个单独的文件,用户可以直接运行,无需复杂的安装步骤。AppImage 文件以.AppImage为后缀,支持大多数主流 Linux 发行版(如Ubuntu、Fedora、Arch Linux等),具有良好的兼容性和便携性。

1.1 AppImage 的优势

  • 跨发行版兼容性:AppImage 可以在大多数 Linux 发行版上运行,无需针对不同发行版单独打包。
  • 无需安装:用户可以直接运行 AppImage 文件,无需使用包管理器安装依赖项。
  • 简化分发:开发者只需生成一个文件即可分发应用程序,极大简化了发布流程。

1.2 快速入门资源

通过 AppImage,开发者和用户都可以更轻松地管理和分发应用程序。接下来,我们将详细介绍如何将 Java 应用程序(Jar包)打包成 AppImage 格式。

2.编写应用并生成 Jar 包

Java 程序开发就按照一般方式进行,这里快速介绍一下。可以通过 maven 提供的快捷脚手架生成一个 Java 项目(目录名称为 artifactId):

1
mvn archetype:generate -DgroupId=com.mk.tool -DartifactId=simple-tool -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

正常编写代码,并生成一个带有全部依赖的 Jar 包,可以使用 maven-assembly-plugin 插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.mk.tool.actionagent.Entry</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>

使用命令行生成 Jar:

1
mvn clean package assembly:single

假设输出的 Jar 包路径为:./target/simple-tool-1.0.0-SNAPSHOT-jar-with-dependencies.jar

3.使用 Jpackage 工具生成需要的资源

3.1 Jpackage 是什么

JPackage 是 Java Development Kit (JDK) 自 JDK 14 起引入的一个命令行工具,旨在简化将 Java 应用程序打包成平台特定格式的过程。这个工具允许开发者为 Windows、macOS 和 Linux 系统创建安装包或软件包,如 .msi 文件(Windows)、.dmg 文件(macOS)和 .deb.rpm 文件(Linux)。使用 JPackage 可以让最终用户更方便地安装 Java 应用程序,并且可以更好地集成到操作系统的环境中,当然,JPackage 工具也支持打包 AppImage 格式。

3.1.1 主要功能

  • 跨平台支持:支持生成适用于 Windows、macOS 和 Linux 的安装包。
  • 自定义图标与描述:可以设置应用程序的图标以及描述信息等元数据。
  • 模块化支持:不仅支持传统的 JAR 文件,还支持基于 Java 模块系统(JPMS)的应用程序。
  • 依赖管理:能够处理应用程序及其运行时所需的依赖项。
  • 启动器生成:自动创建启动脚本或快捷方式,使得应用更容易被启动。
  • 更新机制:提供基础的支持来配置应用程序的自动更新。

3.1.2 示例用法

使用 JPackage 需要指定几个关键参数,包括输入文件的位置、输出格式、目标操作系统等。下面是一个简单的例子,展示如何使用 JPackage 来创建一个 macOS 的 .dmg 包:

1
2
3
4
5
6
jpackage --name MyApp \
--input /path/to/myapp \
--main-jar myapp.jar \
--main-class com.example.MyApp \
--type dmg \
--icon /path/to/icon.icns

这里:

  • --name 指定了应用程序的名字。
  • --input 指向包含所有必要资源的目录。
  • --main-jar 指出主 JAR 文件。
  • --main-class 定义了程序的入口点。
  • --type 设置了输出格式,在此例中为 macOS 的磁盘映像文件。
  • --icon 用于指定应用图标。

3.2 创建 AppImage 需要的文件目录

执行 JPackage 命令:

1
2
3
4
5
6
7
8
9
10
11
jpackage \
--input "./target" \
--main-jar simple-tool-1.0.0-SNAPSHOT-jar-with-dependencies.jar \
--main-class com.mk.tool.simpletool.Entry \
--name simple-tool \
--app-version "1.0.0-SNAPSHOT" \
--vendor "MaphicalYng" \
--description "Simple Tool,示例简单命令行工具。" \
--copyright "Copyright $(date +%Y) MaphicalYng" \
--type app-image \
--dest "./packages"

命令中各个选项的作用:

  • --input: 指定包含应用程序资源的目录。在这个例子中,./target是存放构建输出(如JAR文件)的目录。
  • --main-jar: 指明作为主程序入口点的JAR文件名。这个JAR文件包含了应用及其所有依赖项。
  • --main-class: 指定Java应用程序的主类。当启动应用时,会运行这个类中的public static void main(String[] args)方法。
  • --name: 设置生成的应用程序包或可执行文件的名字。
  • --app-version: 定义应用程序的版本号。
  • --vendor: 应用程序供应商的信息。
  • --description: 提供应用程序的简短描述。
  • --copyright: 添加版权信息到应用程序元数据中。这里使用了shell命令$(date +%Y)来动态插入当前年份。
  • --type: 指定要创建的打包类型。app-image表示将为Linux系统创建一个自包含的应用镜像,它可以在没有安装 Java 的情况下运行。
  • --dest: 指定输出目录,即生成的软件包将被放置的位置。

执行完成之后,将会生成这样一个目录结构和文件:

这个目录就是生成 AppImage 的基础目录,但是还需要进行一些目录结构的调整,让它更匹配标准结构。

3.3 安装 AppImageTool 和 AppRun

3.3.1 简要介绍

AppImageTool 是一个用于创建 AppImage 的工具,它允许开发者将应用程序及其依赖项打包成一个可执行文件,从而在不同的 Linux 发行版上轻松分发和运行。AppRun 则是一个轻量级的运行时环境,它可以帮助用户直接从命令行启动 AppImage 文件,简化了 AppImage 的使用流程。

实际上执行 AppImage 文件就是执行了其中的 AppRun 文件,相当于是整个程序的入口。

3.3.2 下载安装

可以使用下面的脚本自动安装在项目目录中(默认下载 x86_64 架构的可执行文件,若你的环境不同可以修改其中的下载 URL),值得一提的是,这两个程序也是使用的 AppImage 格式,这何尝不是一种自举呢:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/sh

set -e

echo "Setting up AppImage tools..."

# 创建工具目录
TOOLS_DIR="./tools"
mkdir -p "$TOOLS_DIR"

# 从官方 Github 下载 appimagetool
if [ ! -f "$TOOLS_DIR/appimagetool" ]; then
echo "Downloading appimagetool..."
wget -O "$TOOLS_DIR/appimagetool" "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x "$TOOLS_DIR/appimagetool"
fi

# 下载 AppRun
if [ ! -f "$TOOLS_DIR/AppRun" ]; then
echo "Downloading AppRun..."
wget -O "$TOOLS_DIR/AppRun" "https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-x86_64"
chmod +x "$TOOLS_DIR/AppRun"
fi

echo "AppImage tools setup completed!"

3.3 调整目录结构

在正式创建 AppImage 程序包之前,还需要调整一下我们的目录结构以及生成 .desktop 文件,适配 AppRun 工具兼容的标准结构,可以直接执行脚本来生成一个符合条件的目录 appdir

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/sh

set -e

# 设置目录
APP_DIR="./packages/simple-tool"
APPDIR_DIR="./appdir"
TOOLS_DIR="./tools"

echo "Creating AppDir structure..."

# 清理并创建 AppDir
rm -rf "$APPDIR_DIR"
mkdir -p "$APPDIR_DIR"

# 创建标准的 usr 目录结构
mkdir -p "$APPDIR_DIR/usr/bin"
mkdir -p "$APPDIR_DIR/usr/lib"

# 复制应用文件到正确的位置
if [ -f "$APP_DIR/bin/simple-tool" ]; then
cp "$APP_DIR/bin/simple-tool" "$APPDIR_DIR/usr/bin/"
fi

if [ -d "$APP_DIR/lib" ]; then
cp -r "$APP_DIR/lib"/* "$APPDIR_DIR/usr/lib/"
fi

# 使用下载的 AppRun 文件
echo "Using downloaded AppRun..."
cp "$TOOLS_DIR/AppRun" "$APPDIR_DIR/AppRun"
chmod +x "$APPDIR_DIR/AppRun"

# 创建 .desktop 文件
cat > "$APPDIR_DIR/simple-tool.desktop" << EOF
[Desktop Entry]
Name=simple-tool
Comment=Simple Tool,简单的命令行工具。
Exec=simple-tool
Icon=simple-tool
Terminal=true
Type=Application
Categories=Utility;
EOF

# 复制图标
if [ -f "$APP_DIR/lib/simple-tool.png" ]; then
cp "$APP_DIR/lib/simple-tool.png" "$APPDIR_DIR/simple-tool.png"
fi

执行成功后,生成的 appdir 目录结构如下:

现在就可以正式创建 AppImage 了。

3.4 创建 AppImage 可执行文件

执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/sh

set -e

# 设置目录
OUTPUT_DIR="./output"
APPDIR_DIR="./appdir"
TOOLS_DIR="./tools"
APP_VERSION="1.0.0"

echo "Building AppImage..."

# 创建输出目录
rm -rf "$OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"

# 使用 appimagetool 创建 AppImage
if [ -f "$TOOLS_DIR/appimagetool" ]; then
"$TOOLS_DIR/appimagetool" "$APPDIR_DIR" "$OUTPUT_DIR/simple-tool-$APP_VERSION-x86_64.AppImage"
else
echo "Error: appimagetool not found. Please setup first."
exit 1
fi

echo "AppImage built successfully: $OUTPUT_DIR/simple-tool-$APP_VERSION-x86_64.AppImage"

命令输出这样就是创建成功了:

同时,我们的 output 目录下多出一个可执行文件:

4.测试程序

现在,就可以像其他任何可执行文件一样,直接在命令行中执行这个文件了:

到此大功告成,可以把这个文件分发到 x84_64 架构的 Linux 机器上执行了!

以上。


将 Jar 包构建为 AppImage 可执行文件
https://maphical.cn/2025/07/build-jar-to-appimage/
作者
MaphicalYng
发布于
2025年7月6日
许可协议