Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load jawt library relative to sun.boot.library.path system on unix OSes #1422

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -17,6 +17,7 @@ Bug Fixes
* [#1411](https://github.com/java-native-access/jna/pull/1411): Do not throw `Win32Exception` on success for empty section in `Kernel32Util#getPrivateProfileSection` - [@mkarg](https://github.com/mkarg).
* [#1414](https://github.com/java-native-access/jna/pull/1414): Fix definition of `c.s.j.p.unix.X11.XK_Shift_R` - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1323](https://github.com/java-native-access/jna/issues/1323). Fix crashes in direct callbacks on mac OS aarch64 - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1422](https://github.com/java-native-access/jna/pull/1422): Load jawt library relative to `sun.boot.library.path` system on unix OSes - [@matthiasblaesing](https://github.com/matthiasblaesing).

Release 5.10.0
==============
Expand Down
87 changes: 65 additions & 22 deletions native/dispatch.c
Expand Up @@ -3063,23 +3063,23 @@ Java_com_sun_jna_Native_initIDs(JNIEnv *env, jclass cls) {
}

#ifndef NO_JAWT
#if !defined(__APPLE__)
#define JAWT_HEADLESS_HACK
#ifdef _WIN32
#define JAWT_NAME "jawt.dll"
#if defined(_WIN64)
#define METHOD_NAME "JAWT_GetAWT"
#else
#define METHOD_NAME "_JAWT_GetAWT@8"
#endif
#else
#define JAWT_NAME "libjawt.so"
#define METHOD_NAME "JAWT_GetAWT"
#endif
static void* jawt_handle = NULL;
static jboolean (JNICALL *pJAWT_GetAWT)(JNIEnv*,JAWT*);
#define JAWT_GetAWT (*pJAWT_GetAWT)
#endif
#if !defined(__APPLE__)
#define JAWT_HEADLESS_HACK
#ifdef _WIN32
#if defined(_WIN64)
#define METHOD_NAME "JAWT_GetAWT"
#else
#define METHOD_NAME "_JAWT_GetAWT@8"
#endif
#else
#define METHOD_NAME "JAWT_GetAWT"
#endif

static void* jawt_handle = NULL;
static jboolean (JNICALL *pJAWT_GetAWT)(JNIEnv*,JAWT*);

#define JAWT_GetAWT (*pJAWT_GetAWT)
#endif
#endif /* NO_JAWT */

JNIEXPORT jlong JNICALL
Expand Down Expand Up @@ -3116,17 +3116,60 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv* UNUSED_JAWT(env), jclass UNUSED
path = (wchar_t*)alloca(len * sizeof(wchar_t));

swprintf(path, len, L"%s%s", prop, suffix);

free((void *)prop);
}
#undef JAWT_NAME
#define JAWT_NAME path
#endif
if ((jawt_handle = LOAD_LIBRARY(JAWT_NAME, DEFAULT_LOAD_OPTS)) == NULL) {
if ((jawt_handle = LOAD_LIBRARY(path, DEFAULT_LOAD_OPTS)) == NULL) {
char msg[MSG_SIZE];
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(msg, sizeof(msg)));
return -1;
}
#else
const char* jawtLibraryName = "libjawt.so";

// Try to load the libjawt.so library first from the the directories listed
// in the sun.boot.library.path system property. At least Ubuntu builds the
// JDK with RUNPATH set instead of RPATH. The two differ in their effect on
// loading transitive dependencies.
//
// RPATHs effect also covers libraries loaded as transitive dependencies,
// while RUNPATH does not. In the case of JNA libjawt is loaded by
// libdispatch (the native JNA part), which makes it a transtive load.
//
// The solution is to load the library with the full path based on the
// sun.boot.library.path system property, which points to the native library
// dirs.
jstring jprop = get_system_property(env, "sun.boot.library.path");
if (jprop != NULL) {

char* prop = newCString(env, jprop);
char* saveptr;

for(char* propToBeTokeninzed = prop; ; propToBeTokeninzed = NULL) {
char* pathElement = strtok_r(propToBeTokeninzed, ":", &saveptr);

size_t len = strlen(pathElement) + strlen(jawtLibraryName) + 2;
char* path = (char*) alloca(len);

sprintf(path, "%s/%s", pathElement, jawtLibraryName);

jawt_handle = LOAD_LIBRARY(path, DEFAULT_LOAD_OPTS);
if(jawt_handle != NULL || pathElement == NULL) {
break;
}
}

free((void *)prop);
}

if (jawt_handle == NULL) {
if ((jawt_handle = LOAD_LIBRARY(jawtLibraryName, DEFAULT_LOAD_OPTS)) == NULL) {
char msg[MSG_SIZE];
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(msg, sizeof(msg)));
return -1;
}
}
#endif
if ((pJAWT_GetAWT = (void*)FIND_ENTRY(jawt_handle, METHOD_NAME)) == NULL) {
char msg[MSG_SIZE], buf[MSG_SIZE - 31 /* literal characters */ - sizeof(METHOD_NAME)];
snprintf(msg, sizeof(msg), "Error looking up JAWT method %s: %s",
Expand Down