提交 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
* questions. * questions.
*/ */
#include <dlfcn.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <objc/objc-runtime.h>
#include <Security/AuthSession.h> #include <Security/AuthSession.h>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
...@@ -35,16 +35,6 @@ ...@@ -35,16 +35,6 @@
#include "java_props_macosx.h" #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 *getPosixLocale(int cat) {
char *lc = setlocale(cat, NULL); char *lc = setlocale(cat, NULL);
if ((lc == NULL) || (strcmp(lc, "C") == 0)) { if ((lc == NULL) || (strcmp(lc, "C") == 0)) {
...@@ -59,18 +49,70 @@ char *getMacOSXLocale(int cat) { ...@@ -59,18 +49,70 @@ char *getMacOSXLocale(int cat) {
switch (cat) { switch (cat) {
case LC_MESSAGES: case LC_MESSAGES:
{ {
void *jrsFwk = getJRSFramework(); // get preferred language code
if (jrsFwk == NULL) return NULL; CFArrayRef languages = CFLocaleCopyPreferredLanguages();
if (languages == NULL) {
char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage"); return NULL;
char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL; }
if (primaryLanguage == NULL) return NULL; if (CFArrayGetCount(languages) <= 0) {
CFRelease(languages);
return NULL;
}
char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage"); CFStringRef primaryLanguage = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL; if (primaryLanguage == NULL) {
free (primaryLanguage); 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; break;
default: default:
...@@ -90,14 +132,6 @@ char *getMacOSXLocale(int cat) { ...@@ -90,14 +132,6 @@ char *getMacOSXLocale(int cat) {
char *setupMacOSXLocale(int cat) { char *setupMacOSXLocale(int cat) {
char * ret = getMacOSXLocale(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) { if (ret == NULL) {
return getPosixLocale(cat); return getPosixLocale(cat);
} else { } else {
...@@ -124,22 +158,35 @@ int isInAquaSession() { ...@@ -124,22 +158,35 @@ int isInAquaSession() {
return 0; 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) { void setOSNameAndVersion(java_props_t *sprops) {
/* Don't rely on JRSCopyOSName because there's no guarantee the value will // Hardcode os_name, and fill in os_version
* 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.
*/
sprops->os_name = strdup("Mac OS X"); sprops->os_name = strdup("Mac OS X");
void *jrsFwk = getJRSFramework(); char* osVersionCStr = NULL;
if (jrsFwk != NULL) { // Mac OS 10.9 includes the [NSProcessInfo operatingSystemVersion] function,
char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion"); // but it's not in the 10.9 SDK. So, call it via objc_msgSend_stret.
if (copyOSVersion != NULL) { if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
sprops->os_version = copyOSVersion(); OSVerStruct (*procInfoFn)(id rec, SEL sel) = (OSVerStruct(*)(id, SEL))objc_msgSend_stret;
return; 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 @@ ...@@ -134,6 +134,16 @@
"no_NY", "no_NO@nynorsk", "no_NY", "no_NO@nynorsk",
"sr_SP", "sr_YU", "sr_SP", "sr_YU",
"tchinese", "zh_TW", "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 #endif
"", "", "", "",
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册