JDK-8250950 : Allow per-user and system wide configuration of a jpackaged app
  • Type: Enhancement
  • Component: tools
  • Sub-Component: jpackage
  • Affected Version: 14,15,16
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: x86_64
  • Submitted: 2020-08-02
  • Updated: 2022-09-07
  • Resolved: 2022-06-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 19
19 b26Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8288249 :  
Description
ADDITIONAL SYSTEM INFORMATION :
All supported systems, but tested on java 14.0.2+12-46 macOS Catalina 10.15.6 (latest as of today).

A DESCRIPTION OF THE PROBLEM :
When jpackage creates a deployment image, that image contains an embedded configuration file (one of APP_NAME+".cfg", or "Info.plist", or "package.cfg").  Our application requires that each user be able to configure the memory requirements for their usage pattern.  Currently, there appears to be no way to do this.

Additionally, when the user upgrades the application to the next release, any changes they may have made to the predefined configuration file (as listed above) will disappear because the upgrade process will replace it.

My proposed solution would be to prepend another location to the list of directories that are searched for the configuration file.  Looking in Platform::GetConfigFileName(), it would appear that checking Platform::GetAppDataDirectory() first would solve this issue.  (Although checking multiple directories means GetConfigFileName() should probably iterate over directory names, checking each of the possible configuration filenames for each directory.)

I considered an environment variable for the solution, but macOS launches applications via Finder, which is started by launchd, which does have an easily user-configurable way of adding environment variable definitions (that I can tell).



Comments
Changeset: c37c8e5d Author: Alexey Semenyuk <asemenyuk@openjdk.org> Date: 2022-06-06 22:17:59 +0000 URL: https://git.openjdk.java.net/jdk/commit/c37c8e5d34905ff2df34a93aa53dd3369e164596
06-06-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/9025 Date: 2022-06-03 21:07:47 +0000
03-06-2022

This request can be expanded to allow a properties file at either the application level or the user level specific to the application, that could be modified by either the user, an agent, or jpackage itself to control various behaviors of the applauncher when an application is run. The application level file would reside with the applications installation dir (so would be system-wide if the app is installed system-wide) The user level file would reside in the platform specific user application data directory for this app, and would override the system level file. The initial implementation could include properties for: - java-options : overriding the default or cfg file directed options (as requested above) - runtime-search-path : to be used in conjunction with JDK-8208405 to locate an appropriate runtime.
04-11-2020

Additional information received from the submitter =================================== 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.
18-08-2020

The applications ".cfg" file is an internal interface and should not be modified by the user. It reflects the information required by the native packager to launch the app, as determined by the version of jpackage used and the arguments supplied to jpackage by the application developer. 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.
05-08-2020

Request for providing option in jpackage such that the user can tune his memory requirements as per the usage patterns keeping in mind that upgrade to new release does not affect the configuration file produced by jpackage. Submitter has given a possilbe solution.
03-08-2020