提交 1f3787f6 编写于 作者: B bchristi

7131356: (props) "No Java runtime present, requesting install" when creating VM from JNI [macosx]

Summary: Replace JRS calls with Core Foundation calls
Reviewed-by: naoto
上级 20d43859
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,10 +23,10 @@
* questions.
*/
#include <dlfcn.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <objc/objc-runtime.h>
#include <Security/AuthSession.h>
#include <CoreFoundation/CoreFoundation.h>
......@@ -35,16 +35,6 @@
#include "java_props_macosx.h"
// need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded
static void *getJRSFramework() {
static void *jrsFwk = NULL;
if (jrsFwk == NULL) {
jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL);
}
return jrsFwk;
}
char *getPosixLocale(int cat) {
char *lc = setlocale(cat, NULL);
if ((lc == NULL) || (strcmp(lc, "C") == 0)) {
......@@ -59,18 +49,70 @@ char *getMacOSXLocale(int cat) {
switch (cat) {
case LC_MESSAGES:
{
void *jrsFwk = getJRSFramework();
if (jrsFwk == NULL) return NULL;
char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage");
char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL;
if (primaryLanguage == NULL) return NULL;
// get preferred language code
CFArrayRef languages = CFLocaleCopyPreferredLanguages();
if (languages == NULL) {
return NULL;
}
if (CFArrayGetCount(languages) <= 0) {
CFRelease(languages);
return NULL;
}
char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage");
char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL;
free (primaryLanguage);
CFStringRef primaryLanguage = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
if (primaryLanguage == NULL) {
CFRelease(languages);
return NULL;
}
char languageString[LOCALEIDLENGTH];
if (CFStringGetCString(primaryLanguage, languageString,
LOCALEIDLENGTH, CFStringGetSystemEncoding()) == false) {
CFRelease(languages);
return NULL;
}
CFRelease(languages);
// Language IDs use the language designators and (optional) region
// and script designators of BCP 47. So possible formats are:
//
// "en" (language designator only)
// "haw" (3-letter lanuage designator)
// "en-GB" (language with alpha-2 region designator)
// "es-419" (language with 3-digit UN M.49 area code)
// "zh-Hans" (language with ISO 15924 script designator)
//
// In the case of region designators (alpha-2 or UN M.49), we convert
// to our locale string format by changing '-' to '_'. That is, if
// the '-' is followed by fewer than 4 chars.
char* scriptOrRegion = strchr(languageString, '-');
if (scriptOrRegion != NULL && strlen(scriptOrRegion) < 5) {
*scriptOrRegion = '_';
assert((strlen(scriptOrRegion) == 3 &&
// '-' followed by a 2 character region designator
isalpha(scriptOrRegion[1]) &&
isalpha(scriptOrRegion[2])) ||
(strlen(scriptOrRegion) == 4 &&
// '-' followed by a 3-digit UN M.49 area code
isdigit(scriptOrRegion[1]) &&
isdigit(scriptOrRegion[2]) &&
isdigit(scriptOrRegion[3])));
}
const char* retVal = languageString;
return canonicalLanguage;
// Special case for Portuguese in Brazil:
// The language code needs the "_BR" region code (to distinguish it
// from Portuguese in Portugal), but this is missing when using the
// "Portuguese (Brazil)" language.
// If language is "pt" and the current locale is pt_BR, return pt_BR.
char localeString[LOCALEIDLENGTH];
if (strcmp(retVal, "pt") == 0 &&
CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding()) &&
strcmp(localeString, "pt_BR") == 0) {
retVal = localeString;
}
return strdup(retVal);
}
break;
default:
......@@ -90,14 +132,6 @@ char *getMacOSXLocale(int cat) {
char *setupMacOSXLocale(int cat) {
char * ret = getMacOSXLocale(cat);
if (cat == LC_MESSAGES && ret != NULL) {
void *jrsFwk = getJRSFramework();
if (jrsFwk != NULL) {
void (*JRSSetDefaultLocalization)(char *) = dlsym(jrsFwk, "JRSSetDefaultLocalization");
if (JRSSetDefaultLocalization) JRSSetDefaultLocalization(ret);
}
}
if (ret == NULL) {
return getPosixLocale(cat);
} else {
......@@ -124,22 +158,35 @@ int isInAquaSession() {
return 0;
}
// 10.9 SDK does not include the NSOperatingSystemVersion struct.
// For now, create our own
typedef struct {
NSInteger majorVersion;
NSInteger minorVersion;
NSInteger patchVersion;
} OSVerStruct;
void setOSNameAndVersion(java_props_t *sprops) {
/* Don't rely on JRSCopyOSName because there's no guarantee the value will
* remain the same, or even if the JRS functions will continue to be part of
* Mac OS X. So hardcode os_name, and fill in os_version if we can.
*/
// Hardcode os_name, and fill in os_version
sprops->os_name = strdup("Mac OS X");
void *jrsFwk = getJRSFramework();
if (jrsFwk != NULL) {
char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion");
if (copyOSVersion != NULL) {
sprops->os_version = copyOSVersion();
return;
}
char* osVersionCStr = NULL;
// Mac OS 10.9 includes the [NSProcessInfo operatingSystemVersion] function,
// but it's not in the 10.9 SDK. So, call it via objc_msgSend_stret.
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
OSVerStruct (*procInfoFn)(id rec, SEL sel) = (OSVerStruct(*)(id, SEL))objc_msgSend_stret;
OSVerStruct osVer = procInfoFn([NSProcessInfo processInfo],
@selector(operatingSystemVersion));
NSString *nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld",
(long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion];
// Copy out the char*
osVersionCStr = strdup([nsVerStr UTF8String]);
}
if (osVersionCStr == NULL) {
osVersionCStr = strdup("Unknown");
}
sprops->os_version = strdup("Unknown");
sprops->os_version = osVersionCStr;
}
......
......@@ -134,6 +134,16 @@
"no_NY", "no_NO@nynorsk",
"sr_SP", "sr_YU",
"tchinese", "zh_TW",
#endif
#ifdef MACOSX
"sr-Latn", "sr_CS", // Mappings as done by old Apple JRS code
"tk", "tk-Cyrl",
"tt-Latn", "tt-Cyrl",
"uz", "uz_UZ",
"uz-Arab", "uz_UZ",
"uz-Latn", "uz_UZ",
"zh-Hans", "zh_CN",
"zh-Hant", "zh_TW",
#endif
"", "",
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册