JDK-6539705 : JAWT use results in UnsatisfiedLinkError looking for libmawt.so
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: linux
  • CPU: x86
  • Submitted: 2007-03-28
  • Updated: 2018-09-05
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.8-2-k7-smp #1 SMP Tue Aug 16 14:38:08 UTC 2005 i686 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
When running against a custom JNI library linked against JAWT, load of that library fails with an UnsatisfiedLinkError for libmawt.so unless LD_LIBRARY_PATH is explicitly set to include it.

The error was introduced with 1.5 (presumably with the introduction  of the different subdirectories (headless/motif21/xawt) for libmawt.so. So code which runs under 1.4 will not run under 1.5 or 1.6.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile a native method which references something from JAWT into a JNI library.

Load the library in a Java application.

Load fails with UnsatisfiedLinkError.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should not have to explicitly specify location of the mawt library.
ACTUAL -
Custom JNI library is found, but dependent library libmawt.so is not.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.UnsatisfiedLinkError: /path/to/libjnidispatch.so: libmawt.so: cannot open shared object file: No such file or directory

(thrown from System.loadLibrary("jnidispatch"))


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
// Sample native method which references JAWT

#define USE_JAWT
#ifdef USE_JAWT
#include <jawt.h>
// not yet working on OSX
#ifndef __APPLE__
#include <jawt_md.h>
#endif
#endif

JNIEXPORT jint JNICALL
Java_com_sun_jna_Native_getWindowHandle(JNIEnv *env, jobject unused, jobject w) {
  jint handle = 0;
#ifdef USE_JAWT
  JAWT awt;
  awt.version = JAWT_VERSION_1_4;
  if (JAWT_GetAWT(env, &awt)) {
    JAWT_DrawingSurface* ds;
    JAWT_DrawingSurfaceInfo* dsi;
    jint lock;

    ds = awt.GetDrawingSurface(env, w);
    if (ds != NULL) {
      lock = ds->Lock(ds);
      dsi = ds->GetDrawingSurfaceInfo(ds);
      if (dsi != NULL) {
#ifdef _WIN32
        JAWT_Win32DrawingSurfaceInfo* wdsi =
          (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
        handle = (jint)wdsi->hwnd;
#elif __APPLE__
#else
        JAWT_X11DrawingSurfaceInfo* xdsi =
          (JAWT_X11DrawingSurfaceInfo*)dsi->platformInfo;
        handle = xdsi->drawable;
#endif

      }
      ds->Unlock(ds);
      awt.FreeDrawingSurface(ds);
    }
  }
#endif

  if (handle == 0) {
    throwByName(env, "java/lang/UnsupportedOperationException",
                "Can't get native handle");
  }
  return handle;
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Put path to libmawt.so explicitly into LD_LIBRARY_PATH.

Comments
WORK AROUND call System.loadLibrary("awt") before loading the native library.
22-04-2008

EVALUATION I think that for jdk7 the best way to fix is to remove libmawt.so, and build all AWT code into libawt.so again (as we did in 1.4) For 1.6 and 1.5 there is a simple workaround - call System.loadLibrary("awt") before loading the native library.
22-04-2008

EVALUATION We are going to remove MToolkit in 7.0, and so this particular CR could be fixed as soon as MToolkit would be removed from AWT native code. I am reassigning the change request to the person which presumedly would responcible for removing MToolkit.
02-07-2007

SUGGESTED FIX Call System.loadLibrary("awt") before System.loadLibrary("help").
02-04-2007

EVALUATION Since 1.5 we have two distinct toolkits - XToolkit and MToolkit - and corresponding native libraries in AWT. Which library should be loaded is determined in runtime, see the code in src/solaris/native/sun/awt/awt_LoadLibrary.c, however this code is invoked only when AWT library is loaded and skipped when using JAWT. To fix this problem it is enough to load libawt.so in before libjawt.so. I don't know if it must be done in AWT or VM code, but the loading may also be performed in user code.
02-04-2007