Skip to content

Commit

Permalink
Merge pull request #1422 from matthiasblaesing/jawt_loading_fix
Browse files Browse the repository at this point in the history
Load jawt library relative to sun.boot.library.path system on unix OSes
  • Loading branch information
matthiasblaesing committed Mar 14, 2022
2 parents 0774f82 + f57c650 commit 644b708
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 22 deletions.
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

0 comments on commit 644b708

Please sign in to comment.