Hi, I recently discovered that a number of applications making use of JAWT [1] are broken on OpenJDK 7 and 8, while they were working with OpenJDK6.
The docs for JAWT state [1]: """ The final step the most interesting one is to write the native rendering method, with an interface that conforms to the header file that javah generated, and build it as a standard shared library (called myRenderingLib in the above example) by linking it, for the Solaris operating environment, against the jre/lib/sparc/libjawt.so library. """ In other words, JAWT expects third-party native libraries to be linked against libjawt.so. However, nowhere on that page does it say that something like System.loadLibrary("jawt") is needed. In practice, this means that most existing applications rely on libjawt.so being magically found and loaded by the JVM. In OpenJDK6, LD_LIBRARY_PATH was set to a value such that the linker could resolve libjawt.so when a library depending on it was loaded. LD_LIBRARY_PATH was removed for OpenJDK7 [2]. So a number of existing applications fail to work with OpenJDK7 because they can not load libjawt.so. Some applications have been patched to load libjawt.so manually [3], but others haven't (or cant be). The most backwards-compatible fix is to undo the effects of the LD_LIBRARY_PATH change - by setting RUNPATH of the launcher, for example. The build-dev folks suggested that I only do that as a last resort [4]. An alternate fix seems to be to always load libjawt when awt starts up. There might be a small window of time where a third-party library fails to link against libjawt.so but this can happen only if awt has not started up. I would think such a case would not work with OpenJDK6 too since libjawt.so will not be able to resolve the dependency on libxawt.so. libxawt.so is only loaded after awt is started up, and can not be resolved through LD_LIBRARY_PATH. The attached patches for OpenJDK8 and OpenJDK7 attempt this approach. Does anyone have any thoughts or comments? I suspect something like this might be needed for Windows too, but I don't have access to a windows box to verify it. As an aside, should the docs for JAWT [1] be updated? Thanks, Omair [1] http://download.java.net/jdk8/docs/technotes/guides/awt/AWT_Native_Interface.html [2] https://blogs.oracle.com/darcy/entry/purging_ld_library_path [3] http://java-game-lib.svn.sourceforge.net/viewvc/java-game-lib/trunk/LWJGL/src/java/org/lwjgl/LinuxSysImplementation.java?r1=3418&r2=3604 [4] http://mail.openjdk.java.net/pipermail/build-dev/2012-July/006492.html
diff --git a/src/solaris/native/sun/awt/awt_LoadLibrary.c b/src/solaris/native/sun/awt/awt_LoadLibrary.c --- a/src/solaris/native/sun/awt/awt_LoadLibrary.c +++ b/src/solaris/native/sun/awt/awt_LoadLibrary.c @@ -148,6 +148,12 @@ "(Ljava/lang/String;)V", JNU_NewStringPlatform(env, buf)); awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); + /* + * Third-party applications expect libjawt to be available + */ + JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "loadLibrary", + "(Ljava/lang/String;)V", + JNU_NewStringPlatform(env, "jawt")); } return JNI_VERSION_1_2;
diff --git a/src/solaris/native/sun/awt/awt_LoadLibrary.c b/src/solaris/native/sun/awt/awt_LoadLibrary.c --- a/src/solaris/native/sun/awt/awt_LoadLibrary.c +++ b/src/solaris/native/sun/awt/awt_LoadLibrary.c @@ -187,6 +187,13 @@ awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); + /* + * Third-party applications expect libjawt to be available + */ + JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "loadLibrary", + "(Ljava/lang/String;)V", + JNU_NewStringPlatform(env, "jawt")); + return JNI_VERSION_1_2; }