Search code examples
javajava-native-interface

java.lang.UnsatisfiedLinkError: org.thotheolh.jche.NativeBridge.loadPKCS11Module(Ljava/lang/String;)V


I have looked through the UnsatisfiedLinkError helps in StackOverFlow and other search engines but the solutions have not satisfied the problem so I will state them here.

I am trying to make a JNI call to a PKCS11 DLL library and I am getting the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: org.thotheolh.jche.NativeBridge.loadPKCS11Module(Ljava/lang/String;)V
at org.thotheolh.jche.NativeBridge.loadPKCS11Module(Native Method)
at org.thotheolh.jche.NativeBridge.load(NativeBridge.java:40)
at org.thotheolh.jche.NativeBridge.<init>(NativeBridge.java:29)
at org.thotheolh.jche.exception.test.PKCS11GenericTest.main(PKCS11GenericTest.java:27)
Java Result: 1

My native bridge snippet I used to do the 'native' calls below:

NativeBridge.java

public class NativeBridge {

private String pkcs11Module;
private String pkcs11JavaWrapper = "libJPKCS11";

public NativeBridge(String pkcs11Module) throws IOException, NoSuchFieldException {
    this.pkcs11Module = pkcs11Module;
    load();
}

public void load() throws IOException, NoSuchFieldException {
    System.loadLibrary(pkcs11JavaWrapper);
    loadPKCS11Module(pkcs11Module);
}

public synchronized native void loadPKCS11Module(String location) throws IOException;
}

javah generated Header File snippet:

JCHE.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_thotheolh_jche_NativeBridge */

#ifndef _Included_org_thotheolh_jche_NativeBridge
#define _Included_org_thotheolh_jche_NativeBridge
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_thotheolh_jche_NativeBridge
 * Method:    loadPKCS11Module
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module
 (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

C file snippet:

JCHE.c

#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "JCHE.h"

const char *pkcs11ModuleFileLoc;
HMODULE pkcs11;

JNIEXPORT void JNICALL Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module
(JNIEnv *env, jobject obj, jstring location) {
    printf("inside native method\n");
    pkcs11ModuleFileLoc = (*env)->GetStringUTFChars(env, location, (jboolean *)0);
    printf("%s", pkcs11ModuleFileLoc);
    //pkcs11 = LoadLibraryA(pkcs11ModuleFileLoc);
    //printf("\nLoaded PKCS11 Lib");
}

I have attempted to check the loaded libraries in Java and found them already loaded but somehow I am getting the described error despite looking through many other methods available to try and remedy this problem.


Solution

  • Found a very old 2012 Netbeans post to solve the problem. It is due to a few GCC compiler options missing when making the DLL files.

    Additional GCC Compiler Option:

    -Wl,--export-all-symbols -Wl,--add-stdcall-alias 
    

    Reference: http://forums.netbeans.org/post-130319.html