# jstart **Repository Path**: zelde/jstart ## Basic Information - **Project Name**: jstart - **Description**: windows、linux上的java应用启动器 - **Primary Language**: Java - **License**: WTFPL - **Default Branch**: jdk8 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-09-03 - **Last Updated**: 2026-09-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # jstart > java 应用程序的原生启动器 ## 介绍 ​ 一些旧版的 jdk 中提供了`javapackager`来生成一个原生平台的启动器(还包含了生成安装文件的功能),后面又被弃用了,从某个版本的 jdk 开始官方又提供了 `jpackage` 来做同样的事情。官方工具省心,但是也有几个问题: - 生成的启动器是 java 版本相关的,必须包含运行时 - 目录结构不能自定义,不同平台上的目录结构不同 - 不同版本的配置文件也不完全相同 - 每次构建时需要复杂的参数,为每个平台独立构建 当然,也有一些第三方工具解决了部分问题 [jaunch](https://github.com/apposed/jaunch) 为所有主流平台提供了一致的原生启动器和配置文件,但是只支持较新的操作系统。没有包袱的新项目(jdk 17+)建议使用官方的 `jpackage` ## jpackage的目录结构 | 项目 | Windows | Linux | MacOS | | ------------------- | --------------------------- | ------------------------------- | ----------------------------------------------- | | 打包后的根目录 | $YOUR_APP | $YOUR_APP | $YOUR_APP.app | | java 应用的所有文件 | $YOUR_APP/app | $YOUR_APP/lib/app | $YOUR_APP.app/Contents/app | | 启动器配置文件 | $YOUR_APP/app/$YOUR_APP.cfg | $YOUR_APP/lib/app/$YOUR_APP.cfg | $YOUR_APP.app/Contents/app/$YOUR_APP.CFG | | 运行时 | $YOUR_APP/runtime | $YOUR_APP/lib/runtime | $YOUR_APP.app/Contents/runtime | | 启动器 | $YOUR_APP/$YOUR_APP.exe | $YOUR_APP/bin/$YOUR_APP | $YOUR_APP.app/Contents/MacOS/$YOUR_APP | | 启动器图标 | $YOUR_APP/$YOUR_APP.ico | $YOUR_APP/lib/app/$YOUR_APP.png | $YOUR_APP.app/Contents/Resources/$YOUR_APP.icns | | 其他文件 | - | $YOUR_APP/lib/libapplauncher.so | $YOUR_APP.app/Contents/Info.plist | | 其他文件(可选) | - | - | $YOUR_APP.app/Contents/MacOS/_CodeSignature | ## 目标 1. 分离启动器和运行时,支持自定义目录结构 2. 生成平台相关的可执行文件启动器 3. 可配置的jre搜索顺序、虚拟机参数、类路径、java启动类、main方法参数 4. 支持java 8及以上 ## 用法 1. default behavior launcher 2. help actions launcher -v, --version, -h, --help 3. set java-home or/and appdir launcher --java-home path/to/java-home --appdir path/to/appdir 4. use given config file launcher path/to/cfg.toml 5. dry run only launcher --dry-run 2 | 3 | 4 ## 推荐的目录结构(MacOS除外) | 项目 | 目录/文件 | 说明 | | -------------------- | ------------------------------ | --------------------------------------------------- | | 打包后的根目录 | $YOUR_APP | | | 简单 java 应用 | $YOUR_APP/$YOUR_APP.jar | 可选,对于 fatJar 应用可以直接将 mainJar 放在根目录 | | java 应用的所有文件 | $YOUR_APP/app/ | 推荐将所有 java 应用的文件放在一个独立的目录中 | | 资源 | $YOUR_APP/resources | 可选 | | 运行时 | $YOUR_APP/runtime/ | 可选,启动器可以在运行时查找系统 jre | | 启动器在根目录 | $YOUR_APP/$YOUR_APP[.exe] | 可选,对于简单应用启动器可以直接放在根目录 | | 启动器在bin | $YOUR_APP/bin/$YOUR_APP[.exe] | 可选,可以按 Linux 的 FHS 规范放置可执行文件 | | 启动器配置文件1 | $YOUR_APP/$YOUR_APP.cfg | 可选,启动器配置文件可以放在启动器附近 | | 启动器配置文件2 | $YOUR_APP/config/$YOUR_APP.cfg | 可选,启动器配置文件可以独立的 config 目录中 | | 更新时使用的临时目录 | $YOUR_APP/update/ | 可选 | | 当前应用的版本 | version | 可选 | ## 启动器配置文件搜索顺序 1. 启动器所在目录/*启动器简单名*.cfg 4. 当启动器所在目录为 bin 时,启动器所在目录/../config/*启动器简单名*.cfg 5. 当启动器所在目录为 bin 时,启动器所在目录/../app/*启动器简单名*.cfg 4. 当启动器所在目录**不**为 bin 时,启动器所在目录/config/*启动器简单名*.cfg 5. 当启动器所在目录**不**为 bin 时,启动器所在目录/app/*启动器简单名*.cfg ## 启动器配置文件结构(toml) ```toml [Launcher] # 通用配置和常量定义 APPDIR="$LAUNCHER_DIR" JAVA_HOME="$LAUNCHER_DIR/jre" [Runtime] java.minVersion=8 java.path=[ "$APPDIR/runtime", "$APPDIR/jre", "$JAVA_HOME", ":SYSTEM", ] # ... [JavaOptions] java-options=[ "-Duser.dir=$APPDIR", "-Dfile.encoding=UTF-8", ] # ... [Application] app.mainjar="$APPDIR/main-jar.jar" app.mainclass="example.com.MainClass" app.classpath=[ "$APPDIR/lib/dep1.jar", "$APPDIR/lib/dep2.jar", # ... ] # ... ``` ## 启动流程 启动器最多接收两个参数 - 当第一个参数是 --dry-run 时,按照流程执行,在启动实际的 java 应用时,仅输出启动参数(不实际启动,方便测试) - 当第一个参数是 --java-home 时,使用第二个参数作为 $JAVA_HOME 的值处理查找 jre 的逻辑 - 当第一个参数是 xxx.jar 时,使用第二参数传递给 xxx.jar 执行,实际效果为: java -jar xxx.jar ... - 当第一个参数是一个文件时,使用这个文件作为配置文件(不再搜索启动配置文件) - 当第一个参数是一个目录时,使用这个参数作为 $APPDIR(不再解析 $APPDIR路径) - 其他支持的参数为: -h,--help,-v,--version - 参数错误时按 -h 处理 配置文件中支持三个变量: - $JAVA_HOME: 系统环境变量JAVA_HOME 或 通过 --java-home 传递的值 - $LAUNCHER_DIR: 启动器所在目录 - $APPDIR: 启动器启动时解析的结果,可能是配置文件中配置的,可能是传递进来,如果都没有就是