8165524: Better detect JRE that Linux JLI will be using

Reviewed-by: ksrini
This commit is contained in:
Chris Bensen 2016-09-14 06:46:19 -07:00 committed by Kumar Srinivasan
parent aebe74d3f5
commit a7b5545cb8
5 changed files with 90 additions and 40 deletions

View File

@ -112,6 +112,9 @@ GetXUsagePath(char *buf, jint bufsize);
jboolean
GetApplicationHome(char *buf, jint bufsize);
jboolean
GetApplicationHomeFromDll(char *buf, jint bufsize);
#define GetArch() GetArchPath(CURRENT_DATA_MODEL)
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
@ -25,8 +25,49 @@
#include "java.h"
/*
* If app is "/foo/bin/javac", or "/foo/bin/sparcv9/javac" then put
* "/foo" into buf.
* Find the last occurrence of a string
*/
char* findLastPathComponent(char *buffer, const char *comp) {
char* t = buffer;
char* p = NULL;
size_t l = JLI_StrLen(comp);
t = JLI_StrStr(t, comp);
while (t != NULL) {
p = t;
t += l;
t = JLI_StrStr(t, comp);
}
return p;
}
/*
* Removes the trailing file name and any intermediate platform
* directories, if any, and its enclosing directory.
* Ex: if a buffer contains "/foo/bin/javac" or "/foo/bin/x64/javac", the
* truncated resulting buffer will contain "/foo".
*/
jboolean
TruncatePath(char *buf)
{
// try bin directory, maybe an executable
char *p = findLastPathComponent(buf, "/bin/");
if (p != NULL) {
*p = '\0';
return JNI_TRUE;
}
// try lib directory, maybe a library
p = findLastPathComponent(buf, "/lib/");
if (p != NULL) {
*p = '\0';
return JNI_TRUE;
}
return JNI_FALSE;
}
/*
* Retrieves the path to the JRE home by locating the executable file
* of the current process and then truncating the path to the executable
*/
jboolean
GetApplicationHome(char *buf, jint bufsize)
@ -38,26 +79,27 @@ GetApplicationHome(char *buf, jint bufsize)
} else {
return JNI_FALSE;
}
if (JLI_StrRChr(buf, '/') == 0) {
buf[0] = '\0';
return JNI_FALSE;
}
*(JLI_StrRChr(buf, '/')) = '\0'; /* executable file */
if (JLI_StrLen(buf) < 4 || JLI_StrRChr(buf, '/') == 0) {
buf[0] = '\0';
return JNI_FALSE;
}
if (JLI_StrCmp("/bin", buf + JLI_StrLen(buf) - 4) != 0)
*(JLI_StrRChr(buf, '/')) = '\0'; /* sparcv9 or amd64 */
if (JLI_StrLen(buf) < 4 || JLI_StrCmp("/bin", buf + JLI_StrLen(buf) - 4) != 0) {
buf[0] = '\0';
return JNI_FALSE;
}
*(JLI_StrRChr(buf, '/')) = '\0'; /* bin */
return JNI_TRUE;
return TruncatePath(buf);
}
/*
* Retrieves the path to the JRE home by locating the
* shared library and then truncating the path to it.
*/
jboolean
GetApplicationHomeFromDll(char *buf, jint bufsize)
{
/* try to find ourselves instead */
Dl_info info;
if (dladdr((void*)&GetApplicationHomeFromDll, &info) != 0) {
char *path = realpath(info.dli_fname, buf);
if (path == buf) {
return TruncatePath(buf);
}
}
return JNI_FALSE;
}
/*
* Return true if the named program exists
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2015, 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
@ -666,6 +666,7 @@ static jboolean
GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
{
char libjava[MAXPATHLEN];
struct stat s;
if (GetApplicationHome(path, pathsize)) {
/* Is JRE co-located with the application? */
@ -688,6 +689,14 @@ GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
}
}
if (GetApplicationHomeFromDll(path, pathsize)) {
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/%s/" JAVA_DLL, path, arch);
if (stat(libjava, &s) == 0) {
JLI_TraceLauncher("JRE path is %s\n", path);
return JNI_TRUE;
}
}
if (!speculative)
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -348,7 +348,6 @@ GetJREPath(char *path, jint pathsize)
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
}
/*
@ -423,11 +422,11 @@ TruncatePath(char *buf)
*JLI_StrRChr(buf, '\\') = '\0'; /* remove .exe file name */
if ((cp = JLI_StrRChr(buf, '\\')) == 0) {
/* This happens if the application is in a drive root, and
* there is no bin directory. */
* there is no bin directory. */
buf[0] = '\0';
return JNI_FALSE;
}
*cp = '\0'; /* remove the bin\ part */
*cp = '\0'; /* remove the bin\ part */
return JNI_TRUE;
}
@ -449,16 +448,16 @@ GetApplicationHome(char *buf, jint bufsize)
jboolean
GetApplicationHomeFromDll(char *buf, jint bufsize)
{
HMODULE hModule;
DWORD dwFlags =
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
HMODULE module;
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
if (GetModuleHandleEx(dwFlags, (LPCSTR)&GetJREPath, &hModule) == 0) {
return JNI_FALSE;
};
GetModuleFileName(hModule, buf, bufsize);
return TruncatePath(buf);
if (GetModuleHandleEx(flags, (LPCSTR)&GetJREPath, &module) != 0) {
if (GetModuleFileName(module, buf, bufsize) != 0) {
return TruncatePath(buf);
}
}
return JNI_FALSE;
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2015, 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
@ -54,7 +54,4 @@ extern jlong Counter2Micros(jlong counts);
int UnsetEnv(char *name);
jboolean
GetApplicationHomeFromDll(char *buf, jint bufsize);
#endif /* JAVA_MD_H */