【发布时间】:2015-06-12 17:52:55
【问题描述】:
编辑:Oracle 接受我的错误报告,要求以JDK-8138944 : Support command line arguments to the JVM passed to self-contained app launchers 进行增强。
问题
我的团队正在开发一个开源 Java SE 项目 ImageJ,该项目目前有一个用跨平台 C 编写的 custom native launcher。我们希望摆脱这个启动器,转向更现代的行业标准和可维护的部署机制。 JavaFX self-contained applications 是迄今为止我们发现的最有希望的解决方案。
ImageJ 当前本机启动器的一个重要特性是它能够自定义 JVM 的启动方式。例如,你可以写:
ImageJ --debugger=8000 myFile.png
启动器将调用带有标志的JVM:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:8000
同时将 myFile.png 作为 Java 主类的参数。
但从文档中,我们看不到使用 JavaFX 打包工具完成类似任务的方法。
注意事项
我知道UserJvmOptionsService 提供了一种配置 JVM 启动方式的方法(通过内部的 Java Preferences API,JavaFX 启动器在 JVM 启动之前读取该 API)。这非常适合为用户提供一个友好的对话框,他们可以在其中调整最大堆大小和其他常用参数。当然,我们可以在这样的对话框中添加远程调试开关和端口设置,和/或通过 CLI 支持 JVM 配置——但是这需要重新启动应用程序。
理想情况下,我们根本不需要支持这种情况,而是在 JVM 启动后用 Java 处理 all 命令行参数。例如,在大多数情况下,只需在运行时解析 arg 并设置系统属性即可支持-Dfoo=bar 形式的系统属性,只要它在应用程序的启动周期中足够早地完成即可。但显然有很多情况在 JVM 启动之后再做为时已晚:
- 上面的调试例子(你can't enable remote debugging after startup)。
- 堆大小调整
- 垃圾收集调整
- 详细类加载 (
-verbose) - 解释模式 (
-Xint) - Lots of other examples
我们的用户希望能够在 CLI 上传递这些设置,并让 Java 运行时相应地运行 - 对于 ImageJ,向后兼容性尤为重要。
可能的解决方案
我们可以保留本机 C 启动器,替换 Java 打包工具安装的本机可执行文件。但这让我觉得非常脆弱,并且在很大程度上违背了切换到 JavaFX 部署的目的,因为我们仍然需要跨多个不同平台维护、构建和测试自定义本机启动器。
或者,我们可以让应用程序主类成为一个非常薄的 CLI 选项解析器,然后生成 JVM 的第二个实例。这将使引导逻辑保持在纯 Java 中,这将比当前的本机 C 代码更易于维护,同时充分利用 JavaFX 部署方案的跨平台捆绑功能。但这似乎是一个具有潜在挑战性副作用的大技巧。
最后,问题
是否有人通过 JavaFX 自包含应用程序部署实现了对 JVM CLI 参数的支持?如果有,您是如何实现的?如果没有,还有其他建议吗?
【问题讨论】:
标签: java deployment javafx jvm