如何将动态JVM命令行标志传递给独立的JavaFX应用程序? [英] How can dynamic JVM command line flags be passed to a self-contained JavaFX application?

查看:246
本文介绍了如何将动态JVM命令行标志传递给独立的JavaFX应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:Oracle接受我的错误报告请求增强作为 JDK-8138944:支持将JVM的命令行参数传递给自包含应用程序启动器



问题



我的团队正在开发一个开源Java SE项目, ImageJ ,目前有一个自定义本机启动器以跨平台C编写。我们希望远离这个启动器,切换到更现代化的行业标准和可维护的部署机制。 JavaFX自包含的应用程序是迄今为止发现的最有前景的解决方案。



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启动之前读取)。这对于向用户提供友好的对话框很好,他们可以调整最大堆大小和其他常见参数。当然,我们可以在这样一个对话框中添加一个远程调试切换和端口设置,和/或通过CLI支持JVM配置,但需要重启应用程序。



理想情况下,我们完全不需要支持这种情况,而是在Java中启动JVM之后处理所有命令行参数。例如,在大多数情况下,只需解析arg并在运行时设置系统属性,就可以支持窗体 -Dfoo = bar 的系统属性,只要它是在应用程序的启动周期中尽早完成。但是,在JVM启动过后,很明显有很多情况是这样的:





我们的用户希望能够在CLI上传递这些设置,并使Java运行时可以相应地运行,而在ImageJ的情况下,这对于向后兼容性尤为重要。



可能的解决方案




  • 我们可以保留本机C启动器,替换Java包装工具安装的本机可执行文件。但是这让我感到非常脆弱,并且大部分都是为了切换到JavaFX部署的目的,因为我们仍然需要在多个不同的平台上维护,构建和测试自定义本地启动器。


  • 或者,我们可以让应用程序主类是一个非常薄的CLI选项解析器,然后生成JVM的第二个实例。这将使引导逻辑保持在纯Java中,这将比当前的本机C代码更加可维护,同时充分利用JavaFX部署方案的跨平台捆绑功能。但是这似乎是一个可能具有潜在挑战的副作用的大骇客。




最后,问题



有没有人使用JavaFX自包含的应用程序部署来支持JVM CLI参数?如果是,您是如何完成的?如果没有,任何其他建议?

解决方案

您可以通过修改jvm用户覆盖配置文件修改JVM的启动参数API写入:



•Mac〜/ Library / Application Support / [app.preferences.id] /packager/jvmuserargs.cfg
•Windows C: \Users [username] \AppData\Roaming [app.preferences.id] \packager\jvmuserargs.cfg
•Linux〜/ .local / [app.preferences.id] / packager / jvmuserargs。 cfg



注意:这是一个内部实现细节,可能会更改。


EDIT: Oracle accept my bug report requesting an enhancement as JDK-8138944 : Support command line arguments to the JVM passed to self-contained app launchers.

The problem

My team is working on an open source Java SE project, ImageJ, that currently has a custom native launcher written in cross-platform C. We would like to move away from this launcher, switching to a more modern, industry standard and maintainable deployment mechanism. JavaFX self-contained applications are the most promising solution we have found so far.

One great feature of ImageJ's current native launcher is its ability to customize how the JVM is launched. For example, you can write:

ImageJ --debugger=8000 myFile.png

And the launcher will invoke the JVM with flag:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:8000

while keeping the myFile.png as an argument to the Java main class.

But from the docs, we cannot see a way to accomplish something similar with the JavaFX packaging tool.

Considerations

I know that the UserJvmOptionsService provides a means to configure how the JVM is started (via Java Preferences API internally, which the JavaFX launcher reads before JVM startup). This is nice for providing the user with a friendly dialog box where they can tweak maximum heap size and other common parameters. Certainly we could add a remote debugging toggle and port settings to such a dialog box, and/or support JVM configuration via the CLI—but it would then require a restart of the application.

Ideally we would not need to support this scenario at all, and instead would handle all command line arguments after the JVM starts up, in Java. For example, in most cases, system properties of the form -Dfoo=bar can be supported by simply parsing the arg and setting the system property at runtime, as long as it is done early enough in the application's startup cycle. But there are clearly many cases where doing it after JVM startup is too late:

Our users expect to be able to pass these settings on the CLI, and have the Java runtime operate accordingly—and in the case of ImageJ, it is particularly important for backward compatibility.

Possible solutions

  • We could retain the native C launcher, replacing the native executable that the Java packaging tool installs. But this strikes me as highly fragile, and largely defeats the purpose of switching to JavaFX deployment, since we would still need to maintain, build and test the custom native launcher across several different platforms.

  • Alternately, we could have the application main class be a very thin CLI option parser, which then spawns a second instance of the JVM. This would keep the bootstrapping logic in pure Java, which would be far more maintainable than the current native C code, while fully leveraging the JavaFX deployment scheme's cross-platform bundling capabilities. But that seems like a big hack with potentially challenging side effects.

Finally, the question

Has anyone achieved support for JVM CLI arguments with JavaFX self-contained application deployment? If so, how did you accomplish it? If not, any alternative suggestions?

解决方案

You can modify the launch arguments to the JVM by modifying the jvm user overrides config file that the API writes to:

• Mac ~/Library/Application Support/[app.preferences.id]/packager/jvmuserargs.cfg • Windows C:\Users[username]\AppData\Roaming[app.preferences.id]\packager\jvmuserargs.cfg • Linux ~/.local/[app.preferences.id]/packager/jvmuserargs.cfg

NOTE: This is an internal implementation detail and subject to change.

这篇关于如何将动态JVM命令行标志传递给独立的JavaFX应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆