ADDITIONAL SYSTEM INFORMATION :
All platforms that support a Java SE environment.
A DESCRIPTION OF THE PROBLEM :
The following comment was recently added to the JDK-8250950 feature request:
> If individual application user need to run the app with different java vm arguments than were supplied by the application developer, such as to configure memory requirements, the _JAVA_OPTIONS environment variable could be used.
This is not an acceptable approach, as I have detailed below. Since the description below is a wall of text, I will summarize here: Java offers the application developer the promise of "write once, run anywhere" by providing a platform-independent execution environment. The current implementation of jpackage breaks this promise by requiring the application developer to provide a platform-specific launcher in the form of a script that preprocesses a per-user configuration file so that the JDK_JAVA_OPTIONS variable can be set correctly (note that _JAVA_OPTIONS appears to be deprecated). The tooling can (and should) do better than that.
The problem statement was made in the referred to fature request, so I won't repeat it here. Instead, I will describe the only solution that our open source team has come up with and describe why it violates the "write once, run anywhere" assertion and how that violation is easily correctable.
Our team maintains an open source "virtual table top" application. It allows people on different platforms (anywhere a Java SE environment exists) to see the equivalent of a "shared whiteboard" with myriad interactive features. Because this application deals with a large number of images, the memory requirements can vary significantly from one group of users to another (beginning with 1GB of heap on the low end and potentially running as high as 32GB). For reasons dealing with the sometimes transient nature of these images, users prefer to keep the memory settings as low as possible as long as the application still functions properly. This prevents us from setting a particular value that works for everyone.
For our current builds (based on JDK 10), the `jvmuserargs.cfg` file works for us. It is placed in a user accessible location where the contents can be read/written for that partcular user, thus allowing a single installation on a system to be used by multiple different users simultaneously, each with their own memory settings. A perfect solution!
However, the jpackage in incubation for JDK 14 is not upward compatible with that approach. (Should this be a bug report as such upward compatibility is broken?) Because there is no per-user configuration possible, we must create a shell script on macOS and Linux that is executed instead. That script must read a per-user configuration file (probably under ~/.config/ on Linux and ~/Library/Application Support/ on macOS) and extract memory settings so they can be placed into the JDK_JAVA_OPTIONS environment variable prior to executing the Java stub that starts the JVM. Such a script is inherently platform-specific. In addition, a completely different script would be needed (for the same reasons) on Windows 10. And yet another script is needed for any other platforms we try to support in the future.
This is clearly not "write once, run anywhere".
A simple solution exists, however. If the native stub used by jpackage would load the deployment configuration file that is provided by the application developer, then load a per-user configuration file and use it to override settings from the deployment configuration, the Java promise of WORA is kept.
Another option would be for JDK_JAVA_OPTIONS to recognize a leading slash ("/") as meaning a configuration file should be loaded, then the deployment image could set that value to an appropriate pathname for the platform. (This presumes that something like "JDK_JAVA_OPTIONS=$HOME/.config" would translate the $HOME reference into an actual home directory. The macOS plist file does appear to support such references and I presume -- but have not verified -- similar references are possible on other platforms.)
The above isue will exist for any and every Java application that needs per-user customization of JVM configuration parameters (mostly memory size, but possibly GC configuration or other parameters). Is it acceptable to force every application to contain platform-specific scripts when a very simple change to Platform::GetConfigFileName() can correct the issue for all of them?
I reviewed how other Java applications attack this problem. Eclipse, for example, does not have a solution at all, other than installing the application on a per-user basis (multiple installations just to get different memory settings!). The IntelliJ IDEA tool from JetBrains appears to provide its own startup stub that uses its own configuration file scheme (using an approach of two files where the contents of one overrides the contents of the other, similar to what I described above).
Please reconsider this feature request. It is easily possible to support WORA with minimal changes to "share/native/libapplauncher/Platform.cpp", and such support will be valuable to all developers of cross-platform Java applications. The alternative is that Java developers will be doomed to modify their deployment strategy per-platform to compensate for a lack of such support in the core utilities.
Thanks!