最近,我写了一篇关于我们如何解决Java 11 移除 Java 网络启动协议 (JNLP) 问题, JNLP 是我所在组织分发关键业务应用程序的方式。因为我维护了 Linux 上的旧 JNLP 应用程序,但部署到 Windows 桌面,就我所知,这意味着我必须执行一个打包步骤,其中包括在中间 Windows 计算机上创建自定义 Java 11 运行时环境。
这个过程如下所示

中间机器的要求很麻烦;这意味着我需要携带两台机器(当我在路上时不容易管理),或者我需要在我的 Linux 笔记本电脑上安装一个 Windows 虚拟机(我不打算这样做),或者我需要远程访问 Windows 桌面(我们最终选择的解决方案)。
Oracle 的 Alan Bateman 非常友善地写信给我分享了第四种替代方案:将 Windows 版本的 OpenJDK 11 放在 Linux 开发平台上,并从中构建自定义 Java 11 运行时。 根据 Alan 的说法,自 JDK 9 以来,这已经成为可能;他指出“存在一些限制,[Linux 实用程序和 Windows OpenJDK 之间的]版本需要匹配。”
由于这将消除上面概述的一个繁琐的步骤,包括需要远程访问 Windows 桌面,我必须进一步调查。 令我惊讶和高兴的是,我不是 Alan 提到的“少数限制”之一 - 这种方法对我来说效果很好。 但是,我确实发现 Linux 发行版存储库中的 OpenJDK 11 版本与我下载的 Windows OpenJDK 11 “不够接近”,因此我也需要获得相同版本的 Linux OpenJDK 11 并使用它的工具来创建 Java 11 运行时。
新的解决方案
以下是我的新配方详情
- 在方便的地方创建一个项目文件夹。
- 我在 /home/me/src/MyOpenJDK11Project (大概) 创建了我的项目文件夹,并设置了一个名为 MYPROJ_HOME (大概) 的 Bash 环境变量。
- 从 AdoptOpenJDK 获取匹配的 Windows 和 Linux OpenJDK 11 包。
- 将它们都安装在方便的地方(Windows 版本是一个 .zip 文件;Linux 版本是一个 tarball 文件)。
- 我将它们分别安装在 $MYPROJ_HOME/windows 和 $MYPROJ_HOME/linux 中。
- 编写一个 Bash 脚本(或一个 makefile,或一个 Ant 打包步骤,或……)来执行打包。
我的 Bash 脚本解决方案的关键要素是,必须在 NetBeans 创建的 dist 文件夹内运行:
export MYPROJ_HOME=/home/me/src/MyOpenJDK11Project
export W64_JAVA_HOME=$MYPROJ_HOME/windows/jdk-11.0.2+9
export JAVA_HOME=$MYPROJ_HOME/linux/jdk-11.0.2+9
export PATH=$JAVA_HOME/bin:$PATH
export DEPS=`jdeps --print-module-deps MyApplication.jar lib/*`
jlink --module-path $W64_JAVA_HOME/jmods --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules $DEPS --output java-runtime
这会将自定义 Java 11 运行时环境留在 dist 文件夹中,位于名为 java-runtime 的子文件夹中。 我的 Bash 脚本向该文件夹添加了各种 Windows .cmd 文件,用于安装和运行应用程序,这些文件当然也保存在 MYPROJ_HOME 文件夹中。 最后,我的 Bash 脚本压缩完成的 dist 文件夹,并使用 scp 将其放在 Web 服务器上。
结果

效果如何? 首先也是最重要的是,用户看不到任何差异。 从我的角度来看,这个解决方案是一个巨大的胜利,大大简化了打包过程,并消除了打包过程对中间 Windows 机器的需求。 即使我怀念 JNLP 的酷炫,但我实际上更喜欢这个解决方案,因为它让我可以控制 Java 运行时以及应用程序本身,这对我们所有人来说都是一个胜利——用户、系统管理员和我。
有了这些,我再次感谢 Alan Bateman 分享这个绝妙的建议。
2 条评论