You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AppBundler provides a way to store JVM options in user preferences by adding a name field to the option tag (in the AppBundler Ant task). I'm trying to use this feature to allow the user of my application to configure the -Xmx option specifically, without having to modify Info.plist and break the code signing signature. Because the maximum heap memory cannot be changed once the JVM is created, the only way to have it set is by having AppBundler pass the -Xmx option to the JVM it creates.
The problem is that Java's default Preferences.userRoot() is implemented to use the Mac OS X defaults user preferences. As discussed in this article https://hints.macworld.com/article.php?story=20130908042828630 starting with Mavericks, the default preferences are cached by the OS and not flushed when an application restarts. Changes to the preferences are flushed periodically by a daemon or when the user logs out or the system is shut down.
Here is a use case demonstrating the resulting problem: The user of my application changes the maximum memory setting, which changes the -Xmx option to use. My application uses the code example in the AppBundler ant task documentation to put the new value of the option in the proper Preferences.userRoot() node. They restart the application and it still uses the old setting until they logout or reboot.
I don't have a solution to the problem yet, and would happy to hear if anyone else does, especially if it is something that can be made part of AppBundler.
The text was updated successfully, but these errors were encountered:
I’m attaching a self-contained demonstration of the problem. Unpack the tarball, cd to the ShowJVMOptions directory. The tools subdirectory contains a appbundler-1.0ea.jar I built from the latest source, but the actual release 1.0ea jar demonstrates the same problem. To build, run the command ‘ant’. That will create ShowJVMOptons.app in the dist directory.
When the application is run it will open a dialog that shows the value of the -Xmx option that was passed to the JVM, the actual max memory value in the JVM, and the value of the option that is currently read by Java from Preferences.userRoot(). The last will be empty if the test application has never been run before. Enter a new value of the -Xmx option in the inout box. Enter only an integer such as 2048, do not enter something like -Xmx2048M. Click on OK to store the new value in userRoot() preference file and exit the program. If you clear the input box so it is blank, or if you click the Cancel button instead of OK, no new value is written to the userRoot() preference file.
Then run the application again. What you will see is that the preference file has the new value, but the option that AppBundler passes to the JVM has not changed.
If you reboot and try it again, you will see that the new preference is finally used by AppBundler.
There is a mismatch between the way Java on Mac OS implements Preferences.userRoot() and the Mac OS implementation of application user preferences which is what AppBundler’s main.m uses.
The Java implementation is in class MacOSXPreferences which directly reads from and writes to the file backing store that Mac OS uses for its preference implementation. Mac OS, on the other hand documents that preferences should be read and written through the OS API and not through direct manipulation of the backing files. That is because the OS makes heavy use of caching the data read from the files.
This mismatch causes the problem with using the AppBundler facility for named JVM options. Java default userRoot preferences look like they are using the Mac OS user preferences facility, but they aren’t really. Therefore main.m shouldn’t use the Mac OS API to read the preferences, it should read and parse the plist file directly just like Java does.
Original report by me.
AppBundler provides a way to store JVM options in user preferences by adding a name field to the option tag (in the AppBundler Ant task). I'm trying to use this feature to allow the user of my application to configure the -Xmx option specifically, without having to modify Info.plist and break the code signing signature. Because the maximum heap memory cannot be changed once the JVM is created, the only way to have it set is by having AppBundler pass the -Xmx option to the JVM it creates.
The problem is that Java's default Preferences.userRoot() is implemented to use the Mac OS X defaults user preferences. As discussed in this article https://hints.macworld.com/article.php?story=20130908042828630 starting with Mavericks, the default preferences are cached by the OS and not flushed when an application restarts. Changes to the preferences are flushed periodically by a daemon or when the user logs out or the system is shut down.
Here is a use case demonstrating the resulting problem: The user of my application changes the maximum memory setting, which changes the -Xmx option to use. My application uses the code example in the AppBundler ant task documentation to put the new value of the option in the proper Preferences.userRoot() node. They restart the application and it still uses the old setting until they logout or reboot.
I don't have a solution to the problem yet, and would happy to hear if anyone else does, especially if it is something that can be made part of AppBundler.
The text was updated successfully, but these errors were encountered: