<i18n dev> RFR 9 7131356 : (props) "No Java runtime present, requesting install" when creating VM from JNI [macosx]

Alex Strange astrange at apple.com
Mon Jun 13 23:51:26 UTC 2016


> On Jun 13, 2016, at 1:58 PM, Brent Christian <brent.christian at oracle.com> wrote:
> 
> Hi,
> 
> Please review this Mac-only fix:
> 
> http://cr.openjdk.java.net/~bchristi/7131356/webrev.01/
> https://bugs.openjdk.java.net/browse/JDK-7131356
> 
> Thanks go to Gerard Ziemski for the thorough investigation and detailed write-up in the bug report.
> 
> The symptoms:
> 
> On those OS X machines where the default system Java is not installed, any attempt to instantiate JVM from a local JDK (for example via JNI as shown in the bug) presents "No Java installed. Do you want to install Java?" dialog and refuses to run. Clearly, a valid local JDK should be able to run in this case.
> 
> The problem:
> 
> In java_props_macosx.c, there is code that dynamically looks up 4 methods in JavaRuntimeSupport.framework (JRS) and calls into them to find out localized OS version, default locale and the preferred language, but JRS checks for a system available Java and refuses to run if none found.
> 
> Background:
> 
> JavaRuntimeSupport.framework (JRS) is a framework implemented and provided by Apple for use by Java.  It is a "black box" that wraps SPIs required by the Apple-provided implementation of JDK, exposing them to the JDK as APIs.
> 
> Now that the JDK implementation ownership has changed from Apple to Oracle, we have the issue that we don't control the JRS implementation, but rely on Apple to support it for our JDK to continue to run. Depending on a private framework provided by a third party for our code to continue to run doesn't seem like a good long term bet (see also 8024281).
> 
> Proposed solution:
> 
> Apple suggested changing the JDK initialization order so any access to JRS happens only after the JLI_MemAlloc symbol is available.  We believe a better solution is to re-implement the JSR APIs in question, as a move toward eventually dropping reliance on JSR altogether.  The three main changes are:
> 
> 1. In "getMacOSXLocale", re-implement "JRSCopyPrimaryLanguage" using "CFLocaleCopyPreferredLanguages", which gives us the preferred language as set in "System Preferences"->"Language & Text"->"Language" in the form of "xx" (ie. just the language code - ex. "en", "fr", etc.).  The original Apple code then calls into "JRSCopyCanonicalLanguageForPrimaryLanguage" to map "language" into "language_REGION" (ex. "en"-->"en_US", "fr"-->"fr_FR", etc.), though this appears to be unnecessary.  Following the call to setupMacOSXLocale() in ParseLocale()[1], mapLookup() is called to map the language to a default country, per this comment:
> 
>     * If the locale name (without .encoding at variant, if any) matches
>     * any of the names in the locale_aliases list, map it to the
>     * corresponding full locale name.  Most of the entries in the
>     * locale_aliases list are locales that include a language name but
>     * no country name, and this facility is used to map each language
>     * to a default country if that's possible.
> 
> I tried out a few locales, for English (en_US, en_GB), German (de_DE, de_CH) and French (fr_FR, fr_CA).  Language/country system properties behave the same before and after this change, as does the java.util.Locale test attached to the bug.

I think JRSCopyCanonicalLanguageForPrimaryLanguage() may be related to app bundles which don't have localizations in the user's language (for instance a Japanese-only app run on en_US). But I don't have an example of such an app or remember what the right behavior would be.

> 
> 2. In "setupMacOSXLocale" we simply drop the call to "JRSSetDefaultLocalization" as it appears to be a NOP. According to Apple, that API sets up native bundle locale, so that any access to native Cocoa UI (like FileOpenChooser) uses localized strings. Testing shows that this does not seem to work even in Apple's own JDK (ie. JDK 6), so dropping the call to this SPI here does not result in a regression.  An issue was filed to investigate further (8024279, a dup of 8019464) which has since been closed as, "Not an Issue".

This was added a very long time ago so that 'java -jar x.jar' would show properly localized menus in the menubar, instead of English menus, on a non-English system. It might no longer be a problem.

> 
> 3. In "setOSNameAndVersion", re-implement JRSCopyOSVersion using [NSProcessInfo operatingSystemVersion].  (Use of JRSCopyOSName was already removed by 7178922).

You shouldn't need to use objc_msgSend_stret here. If you're not getting a warning when you use @selector in the line above, you should just be able to call -operationgSystemVersion directly inside the if.

If you are getting a warning, it'd be best to declare the selector yourself somewhere higher up:

typedef struct {
        NSInteger majorVersion;
        NSInteger minorVersion;
        NSInteger patchVersion;
} OSVerStruct;

@interface NSProcessInfo ()
- (OSVerStruct)operatingSystemVersion;
@end

> 
> 
> Thanks,
> -Brent
> 
> 1. http://hg.openjdk.java.net/jdk9/dev/jdk/file/79043a1c3547/src/java.base/unix/native/libjava/java_props_md.c
> 



More information about the i18n-dev mailing list