java.lang.UnsatisfiedLinkError returned when calling native method

17,563

Solution 1

When calling a native function in Java, the runtime tries to use:

  • a stdcall-style decorated function: _functionName@n, where n is the number of bytes in the parameter list,
  • and a cdecl-style undecorated function: functionName.

When compiling with MinGW, you will get a mix of these two: MinGW will append the @n, but will not prepend the underscore: functionName@n.

The way to solve this is to tell ld not to add the suffix, using the --kill-at switch (or -Wl,--kill-at if you call it through GCC).

Solution 2

I have found the answer! It seems that when using JNI in Windows it looks for a function starting with _Java_ while in every other platform it looks for Java_. Why this is the case and not written in the documentation I don't know but it make everything work perfectly!

Solution 3

java.lang.UnsatisfiedLinkError: no Sixense_Java in java.library.path

Looks like Java cant find the library, did you put it in the right place?

You might need to change the java.library.path, take a look at this.

If you want to print the contents of it use:

System.out.println( System.getProperties().getProperty("java.library.path"));

This might print a lot, you might want to split(";") and print each entry on its own.

Share:
17,563
yodal
Author by

yodal

Updated on June 04, 2022

Comments

  • yodal
    yodal almost 2 years

    I am trying to make a Java wrapper for a third party DLL. I created my own DLL that acts as a middle man between JNI and the third party DLL. In java I load this DLL fine but the error java.lang.UnsatisfiedLinkError: sixense.Sixense.init()Z is returned. What could be causing this error and how can I debug it properly?

    Main.java:

    package sixense_test;
    
    import sixense.ControllerData;
    import sixense.Sixense;
    
    public class Main {
    
        public static ControllerData[] controllers = new ControllerData[4];
        public static boolean quit;
    
        public static void main(String[] args) {
            if(Sixense.init()) {
                Sixense.setActiveBase(0);
                Sixense.getAllNewestData(controllers);
                System.out.println("X: " + controllers[0].pos[0] + "Y: " + controllers[0].pos[1] + "Z: " + controllers[0].pos[2]);
            }
        }
    }
    

    Sixense.java:

    package sixense;
    
    public class Sixense {
        public static native boolean init();
        public static native boolean exit();
        public static native int getMaxBases();
        public static native boolean setActiveBase( int base_num );
        public static native boolean isBaseConnected( int base_num );
        public static native int getMaxControllers();
        public static native int getNumActiveControllers();
        public static native boolean isControllerEnabled( int controller_id );
        public static native boolean getAllNewestData( ControllerData[] all_data );
        public static native boolean getAllData( int index_back, ControllerData[] all_data );
        public static native boolean getNewestData( int controller_id, ControllerData data );
        public static native boolean getData( int controller_id, int index_back, ControllerData all_data );
        public static native int getHistorySize();
        public static native boolean setFilterEnabled( boolean on_or_off );
        public static native boolean getFilterEnabled();
        public static native boolean setFilterParams( float near_range, float near_val, float far_range, float far_val );
        public static native boolean getFilterParams( float[] params );
        public static native boolean triggerVibration( int controller_id, int duration, int pattern_id );
        public static native boolean autoEnableHemisphereTracking( int controller_id );
        public static native boolean setHighPriorityBinding( boolean on_or_off );
        public static native boolean getHighPriorityBinding();
        public static native boolean setBaseColor( int red, int green, int blue );
        public static native boolean getColorBase( int[] colors );
        static {
            System.loadLibrary("Sixense_Java");
        }
    }
    

    An excerpt from sixense_Sixense.cpp:

    #include <jni.h>
    #include <sixense.h>
    #include "sixense_Sixense.h"
    
    JNIEXPORT jboolean JNICALL Java_sixense_Sixense_init(JNIEnv *env, jclass obj) {
        int i;
        i = sixenseInit();
        return (i == -1) ? JNI_FALSE : JNI_TRUE;
    }
    

    An excerpt from sixense_Sixense.h:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class sixense_Sixense */
    
    #ifndef _Included_sixense_Sixense
    #define _Included_sixense_Sixense
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     sixense_Sixense
     * Method:    init
     * Signature: ()Z
     */
    JNIEXPORT jboolean JNICALL Java_sixense_Sixense_init
      (JNIEnv *, jclass);
    

    Output from dumpbin:

    File Type: DLL
    
      Section contains the following exports for Sixense_Java.dll
    
        00000000 characteristics
        4FFBC481 time date stamp Tue Jul 10 01:58:25 2012
            0.00 version
               1 ordinal base
              23 number of functions
              23 number of names
    
        ordinal hint RVA      name
    
              1    0 00001D10 Java_sixense_Sixense_autoEnableHemisphereTracking@12
              2    1 000011A0 Java_sixense_Sixense_exit@8
              3    2 00001A40 Java_sixense_Sixense_getAllData@16
              4    3 000019A0 Java_sixense_Sixense_getAllNewestData@12
              5    4 00001DC0 Java_sixense_Sixense_getColorBase@12
              6    5 00001B30 Java_sixense_Sixense_getData@20
              7    6 00001BD0 Java_sixense_Sixense_getFilterEnabled@8
              8    7 00001C40 Java_sixense_Sixense_getFilterParams@12
              9    8 00001D60 Java_sixense_Sixense_getHighPriorityBinding@8
             10    9 00001B90 Java_sixense_Sixense_getHistorySize@8
             11    A 000011C0 Java_sixense_Sixense_getMaxBases@8
             12    B 00001210 Java_sixense_Sixense_getMaxControllers@8
             13    C 00001AE0 Java_sixense_Sixense_getNewestData@16
             14    D 00001220 Java_sixense_Sixense_getNumActiveControllers@8
             15    E 00001180 Java_sixense_Sixense_init@8
             16    F 000011F0 Java_sixense_Sixense_isBaseConnected@12
             17   10 00001230 Java_sixense_Sixense_isControllerEnabled@12
             18   11 000011D0 Java_sixense_Sixense_setActiveBase@12
             19   12 00001D90 Java_sixense_Sixense_setBaseColor@20
             20   13 00001BA0 Java_sixense_Sixense_setFilterEnabled@12
             21   14 00001C00 Java_sixense_Sixense_setFilterParams@24
             22   15 00001D30 Java_sixense_Sixense_setHighPriorityBinding@12
             23   16 00001CE0 Java_sixense_Sixense_triggerVibration@20
    
      Summary
    
            1000 .bss
            1000 .data
            1000 .edata
            1000 .idata
            1000 .rdata
            1000 .reloc
            2000 .text