134 lines
4.8 KiB
Markdown
134 lines
4.8 KiB
Markdown
## 便携式 JRE/JDK8 集成指南
|
||
|
||
本指南介绍如何将 JRE 8 以“便携式”(解压即用、无需安装)的方式随应用打包,并在 Electron 主进程中通过绝对路径调用,从而避免要求用户在系统中安装 JDK/JRE。
|
||
|
||
### 为什么选择便携式 JRE
|
||
- 无需管理员权限与系统环境变量配置,用户无感知。
|
||
- 不污染系统环境(不写入 JAVA_HOME/PATH)。
|
||
- 跨平台一致,可精简体积、可控版本。
|
||
|
||
### 适用场景
|
||
- 运行 Java 程序或 JAR 包(仅需运行时)。
|
||
- 不需要 javac/jcmd/jmap 等开发/诊断工具(若需要,请改为随包便携式 JDK)。
|
||
|
||
### 推荐的 JRE 8 发行版(可再分发)
|
||
- Azul Zulu 8 JRE(可选 ZuluFX 含 JavaFX):[下载页面](https://www.azul.com/downloads/?version=java-8-lts&package=jre)
|
||
- BellSoft Liberica 8 JRE(Standard/Full,Full 含 JavaFX):[下载页面](https://bell-sw.com/pages/downloads/#/java-8-lts)
|
||
- Eclipse Temurin 8 JRE(Adoptium):[下载页面](https://adoptium.net/temurin/releases/?version=8)
|
||
|
||
选择要点:
|
||
- 需要 AWT/Swing/字体/打印 → 选择非 headless 包。
|
||
- 需要 JavaFX → 选择 Liberica Full 或 ZuluFX。
|
||
- 仅命令行/服务端 → 任意 JRE 8(headless 也可)。
|
||
|
||
### 目录放置约定
|
||
将解压后的 JRE 放入项目的 `build/extraResources/jre`,保证内部存在 `bin/java(.exe)`:
|
||
|
||
```
|
||
build/
|
||
extraResources/
|
||
jre/
|
||
bin/
|
||
java(.exe)
|
||
lib/
|
||
...
|
||
```
|
||
|
||
构建后在生产环境可通过 `process.resourcesPath` 访问:
|
||
`<app>/resources/extraResources/jre/bin/java(.exe)`。
|
||
|
||
### 主进程调用示例
|
||
在 `electron/preload/lifecycle.js` 或你的业务模块中封装 Java 运行工具(开发/生产两种路径):
|
||
|
||
```js
|
||
const path = require('path');
|
||
const { spawn } = require('child_process');
|
||
|
||
function getExtraResourcesDir() {
|
||
// 开发态:使用项目目录;生产态:使用 asar/resources 目录
|
||
const isDev = !!process.env.EE_DEV || process.env.NODE_ENV === 'development';
|
||
return isDev
|
||
? path.join(process.cwd(), 'build', 'extraResources')
|
||
: path.join(process.resourcesPath, 'extraResources');
|
||
}
|
||
|
||
function getJavaBinPath() {
|
||
const extraDir = getExtraResourcesDir();
|
||
const javaBinName = process.platform === 'win32' ? 'java.exe' : 'java';
|
||
return path.join(extraDir, 'jre', 'bin', javaBinName);
|
||
}
|
||
|
||
function runJavaJar(jarAbsPath, args = [], options = {}) {
|
||
const javaPath = getJavaBinPath();
|
||
const child = spawn(javaPath, ['-jar', jarAbsPath, ...args], {
|
||
stdio: 'inherit',
|
||
...options,
|
||
});
|
||
return child;
|
||
}
|
||
|
||
async function ensureJavaVersion(logger) {
|
||
return new Promise((resolve) => {
|
||
const child = spawn(getJavaBinPath(), ['-version']);
|
||
let out = '';
|
||
let err = '';
|
||
child.stdout && child.stdout.on('data', (d) => (out += d.toString()))
|
||
child.stderr && child.stderr.on('data', (d) => (err += d.toString()))
|
||
child.on('close', () => {
|
||
const text = (out + '\n' + err).trim();
|
||
logger && logger.info('[java] version check:', text);
|
||
resolve(text.includes('1.8.0'));
|
||
});
|
||
});
|
||
}
|
||
|
||
module.exports = { getJavaBinPath, runJavaJar, ensureJavaVersion };
|
||
```
|
||
|
||
在生命周期中调用(示例):
|
||
|
||
```js
|
||
const { logger } = require('ee-core/log');
|
||
const path = require('path');
|
||
const { runJavaJar, ensureJavaVersion } = require('./java-runner');
|
||
|
||
class Lifecycle {
|
||
async ready() {
|
||
const ok = await ensureJavaVersion(logger);
|
||
if (!ok) {
|
||
logger.error('[java] 未检测到 JRE 8,请检查 extraResources/jre 是否存在');
|
||
}
|
||
}
|
||
|
||
async windowReady() {
|
||
const jarPath = path.join(process.resourcesPath || process.cwd(), 'extraResources', 'tools', 'your-app.jar');
|
||
// 示例:延后在某业务时机再启动 Java 进程
|
||
// const proc = runJavaJar(jarPath, ['--arg1', 'value']);
|
||
}
|
||
}
|
||
```
|
||
|
||
注意:示例中的 `java-runner` 为上文工具函数文件,实际请按你的项目结构放置。
|
||
|
||
### 验证清单
|
||
- 运行 `jre/bin/java -version` 输出包含 `1.8.0_xxx`。
|
||
- 若涉及 GUI/字体/打印,验证 AWT/Swing 中文渲染与打印。
|
||
- 若需 JavaFX,验证 JavaFX Demo 启动。
|
||
- 若涉及 TLS/HTTPS,验证 SSL 通信正常。
|
||
|
||
### 许可与合规
|
||
- Azul Zulu、Eclipse Temurin(Adoptium)、BellSoft Liberica 的 JRE/JDK 8 发行包均可免费再分发(GPLv2+CE 或厂商许可证)。
|
||
- 建议在应用的“关于/许可证”中附上所选发行版的许可证链接与致谢。
|
||
|
||
### 常见问题
|
||
1) 是否“阉割”?
|
||
— 上述 JRE 8 发行版均为标准运行时,通过兼容性测试;JRE 不包含开发者工具属于正常区别,不是删减。
|
||
|
||
2) 何时需要 JDK 而不是 JRE?
|
||
— 需要 `javac` 编译或 `jcmd/jmap` 等诊断工具,或你的 Java 组件依赖 `tools.jar` 时。
|
||
|
||
3) 体积如何优化?
|
||
— 选择 headless(若无 GUI 需求)、去除无用语言/字体包;或改用 JDK 9+ 使用 jlink(不适用于 8)。
|
||
|
||
|